Merge "Report resolution stop" into main
diff --git a/Cronet/tests/mts/jarjar_excludes.txt b/Cronet/tests/mts/jarjar_excludes.txt
index e8fd39b..a0ce5c2 100644
--- a/Cronet/tests/mts/jarjar_excludes.txt
+++ b/Cronet/tests/mts/jarjar_excludes.txt
@@ -1,3 +1,5 @@
+# Exclude some test prefixes, as they can't be found after being jarjared.
+com\.android\.testutils\..+
# jarjar-gen can't handle some kotlin object expression, exclude packages that include them
androidx\..+
kotlin\.test\..+
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 76e4af8..d33453c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -140,6 +140,9 @@
},
{
"name": "FrameworksNetTests"
+ },
+ {
+ "name": "NetHttpCoverageTests"
}
],
"mainline-presubmit": [
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
index 062ecc5..119fbc6 100644
--- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -17,7 +17,8 @@
package com.android.networkstack.tethering.apishim.api31;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
import android.net.IpPrefix;
import android.net.MacAddress;
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 6affb62..56b5c2e 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -28,11 +28,11 @@
import static android.net.TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
import static android.net.util.NetworkConstants.asByte;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
import static com.android.networkstack.tethering.UpstreamNetworkState.isVcnInterface;
import static com.android.networkstack.tethering.util.PrefixUtils.asIpPrefix;
import static com.android.networkstack.tethering.util.TetheringMessageBase.BASE_IPSERVER;
diff --git a/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java b/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
index 18c2171..50d6c4b 100644
--- a/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
+++ b/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
@@ -16,7 +16,6 @@
package android.net.ip;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.IPPROTO_ICMPV6;
import static android.system.OsConstants.SOCK_RAW;
@@ -30,6 +29,7 @@
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_AUTONOMOUS;
import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_ON_LINK;
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
import static com.android.net.module.util.NetworkStackConstants.TAG_SYSTEM_NEIGHBOR;
import static com.android.networkstack.tethering.util.TetheringUtils.getAllNodesForScopeId;
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index b1f875b..4413d26 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -20,6 +20,8 @@
import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SOCK_STREAM;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_DESTROY;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_NEW;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_AIDL;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
@@ -34,6 +36,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -57,7 +60,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor;
@@ -75,8 +77,9 @@
private OffloadHardwareInterface mOffloadHw;
private OffloadHalCallback mOffloadHalCallback;
- @Mock private IOffloadHal mIOffload;
- @Mock private NativeHandle mNativeHandle;
+ private IOffloadHal mIOffload;
+ private NativeHandle mNativeHandle1;
+ private NativeHandle mNativeHandle2;
// Random values to test Netlink message.
private static final short TEST_TYPE = 184;
@@ -97,7 +100,9 @@
@Override
public NativeHandle createConntrackSocket(final int groups) {
- return mNativeHandle;
+ return groups == (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY)
+ ? mNativeHandle1
+ : mNativeHandle2;
}
}
@@ -105,45 +110,89 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mOffloadHalCallback = new OffloadHalCallback();
- when(mIOffload.initOffload(any(NativeHandle.class), any(NativeHandle.class),
- any(OffloadHalCallback.class))).thenReturn(true);
+ mIOffload = mock(IOffloadHal.class);
}
- private void startOffloadHardwareInterface(int offloadHalVersion)
+ private void startOffloadHardwareInterface(int offloadHalVersion, boolean isHalInitSuccess)
throws Exception {
+ startOffloadHardwareInterface(offloadHalVersion, isHalInitSuccess, mock(NativeHandle.class),
+ mock(NativeHandle.class));
+ }
+
+ private void startOffloadHardwareInterface(int offloadHalVersion, boolean isHalInitSuccess,
+ NativeHandle handle1, NativeHandle handle2) throws Exception {
final SharedLog log = new SharedLog("test");
final Handler handler = new Handler(mTestLooper.getLooper());
- final int num = offloadHalVersion != OFFLOAD_HAL_VERSION_NONE ? 1 : 0;
+ final boolean hasNullHandle = handle1 == null || handle2 == null;
+ // If offloadHalVersion is OFFLOAD_HAL_VERSION_NONE or it has null NativeHandle arguments,
+ // mIOffload.initOffload() shouldn't be called.
+ final int initNum = (offloadHalVersion != OFFLOAD_HAL_VERSION_NONE && !hasNullHandle)
+ ? 1
+ : 0;
+ // If it is HIDL or has null NativeHandle argument, NativeHandles should be closed.
+ final int handleCloseNum = (hasNullHandle
+ || offloadHalVersion == OFFLOAD_HAL_VERSION_HIDL_1_0
+ || offloadHalVersion == OFFLOAD_HAL_VERSION_HIDL_1_1) ? 1 : 0;
+ mNativeHandle1 = handle1;
+ mNativeHandle2 = handle2;
+ when(mIOffload.initOffload(any(NativeHandle.class), any(NativeHandle.class),
+ any(OffloadHalCallback.class))).thenReturn(isHalInitSuccess);
mOffloadHw = new OffloadHardwareInterface(handler, log,
new MyDependencies(handler, log, offloadHalVersion));
- assertEquals(offloadHalVersion, mOffloadHw.initOffload(mOffloadHalCallback));
- verify(mIOffload, times(num)).initOffload(any(NativeHandle.class), any(NativeHandle.class),
- eq(mOffloadHalCallback));
+ assertEquals(isHalInitSuccess && !hasNullHandle
+ ? offloadHalVersion
+ : OFFLOAD_HAL_VERSION_NONE,
+ mOffloadHw.initOffload(mOffloadHalCallback));
+ verify(mIOffload, times(initNum)).initOffload(any(NativeHandle.class),
+ any(NativeHandle.class), eq(mOffloadHalCallback));
+ if (mNativeHandle1 != null) verify(mNativeHandle1, times(handleCloseNum)).close();
+ if (mNativeHandle2 != null) verify(mNativeHandle2, times(handleCloseNum)).close();
}
@Test
public void testInitFailureWithNoHal() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_NONE);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_NONE, true);
}
@Test
public void testInitSuccessWithAidl() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_AIDL);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_AIDL, true);
}
@Test
public void testInitSuccessWithHidl_1_0() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
}
@Test
public void testInitSuccessWithHidl_1_1() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1, true);
+ }
+
+ @Test
+ public void testInitFailWithAidl() throws Exception {
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_AIDL, false);
+ }
+
+ @Test
+ public void testInitFailWithHidl_1_0() throws Exception {
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, false);
+ }
+
+ @Test
+ public void testInitFailWithHidl_1_1() throws Exception {
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1, false);
+ }
+
+ @Test
+ public void testInitFailDueToNullHandles() throws Exception {
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_AIDL, true, mock(NativeHandle.class),
+ null);
}
@Test
public void testGetForwardedStats() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
ForwardedStats stats = new ForwardedStats(12345, 56780);
when(mIOffload.getForwardedStats(anyString())).thenReturn(stats);
assertEquals(mOffloadHw.getForwardedStats(RMNET0), stats);
@@ -152,7 +201,7 @@
@Test
public void testSetLocalPrefixes() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
final ArrayList<String> localPrefixes = new ArrayList<>();
localPrefixes.add("127.0.0.0/8");
localPrefixes.add("fe80::/64");
@@ -165,7 +214,7 @@
@Test
public void testSetDataLimit() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
final long limit = 12345;
when(mIOffload.setDataLimit(anyString(), anyLong())).thenReturn(true);
assertTrue(mOffloadHw.setDataLimit(RMNET0, limit));
@@ -177,7 +226,7 @@
@Test
public void testSetDataWarningAndLimitFailureWithHidl_1_0() throws Exception {
// Verify V1.0 control HAL would reject the function call with exception.
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
final long warning = 12345;
final long limit = 67890;
assertThrows(UnsupportedOperationException.class,
@@ -187,7 +236,7 @@
@Test
public void testSetDataWarningAndLimit() throws Exception {
// Verify V1.1 control HAL could receive this function call.
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1, true);
final long warning = 12345;
final long limit = 67890;
when(mIOffload.setDataWarningAndLimit(anyString(), anyLong(), anyLong())).thenReturn(true);
@@ -199,7 +248,7 @@
@Test
public void testSetUpstreamParameters() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
final String v4addr = "192.168.10.1";
final String v4gateway = "192.168.10.255";
final ArrayList<String> v6gws = new ArrayList<>(0);
@@ -220,7 +269,7 @@
@Test
public void testUpdateDownstream() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
final String ifName = "wlan1";
final String prefix = "192.168.43.0/24";
when(mIOffload.addDownstream(anyString(), anyString())).thenReturn(true);
@@ -237,7 +286,7 @@
@Test
public void testSendIpv4NfGenMsg() throws Exception {
- startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0, true);
FileDescriptor writeSocket = new FileDescriptor();
FileDescriptor readSocket = new FileDescriptor();
try {
@@ -246,9 +295,9 @@
fail();
return;
}
- when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket);
+ when(mNativeHandle1.getFileDescriptor()).thenReturn(writeSocket);
- mOffloadHw.sendIpv4NfGenMsg(mNativeHandle, TEST_TYPE, TEST_FLAGS);
+ mOffloadHw.sendIpv4NfGenMsg(mNativeHandle1, TEST_TYPE, TEST_FLAGS);
ByteBuffer buffer = ByteBuffer.allocate(9823); // Arbitrary value > expectedLen.
buffer.order(ByteOrder.nativeOrder());
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 9c6904d..770507e 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -68,6 +68,7 @@
import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST;
@@ -157,7 +158,6 @@
import android.net.ip.DadProxy;
import android.net.ip.IpServer;
import android.net.ip.RouterAdvertisementDaemon;
-import android.net.util.NetworkConstants;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
@@ -559,7 +559,7 @@
prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
prop.addLinkAddress(
new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
- NetworkConstants.RFC7421_PREFIX_LENGTH));
+ RFC7421_PREFIX_LENGTH));
prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
InetAddresses.parseNumericAddress("2001:db8::1"),
interfaceName, RTN_UNICAST));
diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h
index be604f9..dcf6d6a 100644
--- a/bpf_progs/netd.h
+++ b/bpf_progs/netd.h
@@ -55,21 +55,22 @@
} StatsValue;
STRUCT_SIZE(StatsValue, 4 * 8); // 32
+#ifdef __cplusplus
+static inline StatsValue& operator+=(StatsValue& lhs, const StatsValue& rhs) {
+ lhs.rxPackets += rhs.rxPackets;
+ lhs.rxBytes += rhs.rxBytes;
+ lhs.txPackets += rhs.txPackets;
+ lhs.txBytes += rhs.txBytes;
+ return lhs;
+}
+#endif
+
typedef struct {
char name[IFNAMSIZ];
} IfaceValue;
STRUCT_SIZE(IfaceValue, 16);
typedef struct {
- uint64_t rxBytes;
- uint64_t rxPackets;
- uint64_t txBytes;
- uint64_t txPackets;
- uint64_t tcpRxPackets;
- uint64_t tcpTxPackets;
-} Stats;
-
-typedef struct {
uint64_t timestampNs;
uint32_t ifindex;
uint32_t length;
diff --git a/framework-t/api/OWNERS b/framework-t/api/OWNERS
index de0f905..af583c3 100644
--- a/framework-t/api/OWNERS
+++ b/framework-t/api/OWNERS
@@ -1 +1,2 @@
file:platform/packages/modules/Connectivity:master:/nearby/OWNERS
+file:platform/packages/modules/Connectivity:master:/remoteauth/OWNERS
diff --git a/service-t/jni/com_android_server_net_NetworkStatsService.cpp b/service-t/jni/com_android_server_net_NetworkStatsService.cpp
index 8d8dc32..4a6e733 100644
--- a/service-t/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/service-t/jni/com_android_server_net_NetworkStatsService.cpp
@@ -47,11 +47,11 @@
RX_PACKETS = 1,
TX_BYTES = 2,
TX_PACKETS = 3,
- TCP_RX_PACKETS = 4,
- TCP_TX_PACKETS = 5
+ TCP_RX_PACKETS = 4, // not supported, always returns UNKNOWN (-1)
+ TCP_TX_PACKETS = 5, // not supported, always returns UNKNOWN (-1)
};
-static uint64_t getStatsType(Stats* stats, StatsType type) {
+static uint64_t getStatsType(StatsValue* stats, StatsType type) {
switch (type) {
case RX_BYTES:
return stats->rxBytes;
@@ -62,16 +62,14 @@
case TX_PACKETS:
return stats->txPackets;
case TCP_RX_PACKETS:
- return stats->tcpRxPackets;
case TCP_TX_PACKETS:
- return stats->tcpTxPackets;
default:
return UNKNOWN;
}
}
static jlong nativeGetTotalStat(JNIEnv* env, jclass clazz, jint type) {
- Stats stats = {};
+ StatsValue stats = {};
if (bpfGetIfaceStats(NULL, &stats) == 0) {
return getStatsType(&stats, (StatsType) type);
@@ -86,7 +84,7 @@
return UNKNOWN;
}
- Stats stats = {};
+ StatsValue stats = {};
if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
return getStatsType(&stats, (StatsType) type);
@@ -96,7 +94,7 @@
}
static jlong nativeGetIfIndexStat(JNIEnv* env, jclass clazz, jint ifindex, jint type) {
- Stats stats = {};
+ StatsValue stats = {};
if (bpfGetIfIndexStats(ifindex, &stats) == 0) {
return getStatsType(&stats, (StatsType) type);
} else {
@@ -105,7 +103,7 @@
}
static jlong nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
- Stats stats = {};
+ StatsValue stats = {};
if (bpfGetUidStats(uid, &stats) == 0) {
return getStatsType(&stats, (StatsType) type);
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
index 2e6e3e5..fed2979 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
@@ -40,39 +40,26 @@
using base::Result;
-// This explicitly zero-initializes the relevant Stats fields.
-void InitStats(Stats* stats) {
- stats->rxBytes = 0;
- stats->rxPackets = 0;
- stats->txBytes = 0;
- stats->txPackets = 0;
- stats->tcpRxPackets = -1;
- stats->tcpTxPackets = -1;
-}
-
-int bpfGetUidStatsInternal(uid_t uid, Stats* stats,
+int bpfGetUidStatsInternal(uid_t uid, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& appUidStatsMap) {
- InitStats(stats);
auto statsEntry = appUidStatsMap.readValue(uid);
- if (statsEntry.ok()) {
- stats->rxPackets = statsEntry.value().rxPackets;
- stats->txPackets = statsEntry.value().txPackets;
- stats->rxBytes = statsEntry.value().rxBytes;
- stats->txBytes = statsEntry.value().txBytes;
+ if (!statsEntry.ok()) {
+ *stats = {};
+ return (statsEntry.error().code() == ENOENT) ? 0 : -statsEntry.error().code();
}
- return (statsEntry.ok() || statsEntry.error().code() == ENOENT) ? 0
- : -statsEntry.error().code();
+ *stats = statsEntry.value();
+ return 0;
}
-int bpfGetUidStats(uid_t uid, Stats* stats) {
+int bpfGetUidStats(uid_t uid, StatsValue* stats) {
static BpfMapRO<uint32_t, StatsValue> appUidStatsMap(APP_UID_STATS_MAP_PATH);
return bpfGetUidStatsInternal(uid, stats, appUidStatsMap);
}
-int bpfGetIfaceStatsInternal(const char* iface, Stats* stats,
+int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
const BpfMap<uint32_t, IfaceValue>& ifaceNameMap) {
- InitStats(stats);
+ *stats = {};
int64_t unknownIfaceBytesTotal = 0;
const auto processIfaceStats =
[iface, stats, &ifaceNameMap, &unknownIfaceBytesTotal](
@@ -88,10 +75,7 @@
if (!statsEntry.ok()) {
return statsEntry.error();
}
- stats->rxPackets += statsEntry.value().rxPackets;
- stats->txPackets += statsEntry.value().txPackets;
- stats->rxBytes += statsEntry.value().rxBytes;
- stats->txBytes += statsEntry.value().txBytes;
+ *stats += statsEntry.value();
}
return Result<void>();
};
@@ -99,27 +83,24 @@
return res.ok() ? 0 : -res.error().code();
}
-int bpfGetIfaceStats(const char* iface, Stats* stats) {
+int bpfGetIfaceStats(const char* iface, StatsValue* stats) {
static BpfMapRO<uint32_t, StatsValue> ifaceStatsMap(IFACE_STATS_MAP_PATH);
static BpfMapRO<uint32_t, IfaceValue> ifaceIndexNameMap(IFACE_INDEX_NAME_MAP_PATH);
return bpfGetIfaceStatsInternal(iface, stats, ifaceStatsMap, ifaceIndexNameMap);
}
-int bpfGetIfIndexStatsInternal(uint32_t ifindex, Stats* stats,
+int bpfGetIfIndexStatsInternal(uint32_t ifindex, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap) {
- InitStats(stats);
auto statsEntry = ifaceStatsMap.readValue(ifindex);
- if (statsEntry.ok()) {
- stats->rxPackets = statsEntry.value().rxPackets;
- stats->txPackets = statsEntry.value().txPackets;
- stats->rxBytes = statsEntry.value().rxBytes;
- stats->txBytes = statsEntry.value().txBytes;
- return 0;
+ if (!statsEntry.ok()) {
+ *stats = {};
+ return (statsEntry.error().code() == ENOENT) ? 0 : -statsEntry.error().code();
}
- return (statsEntry.error().code() == ENOENT) ? 0 : -statsEntry.error().code();
+ *stats = statsEntry.value();
+ return 0;
}
-int bpfGetIfIndexStats(int ifindex, Stats* stats) {
+int bpfGetIfIndexStats(int ifindex, StatsValue* stats) {
static BpfMapRO<uint32_t, StatsValue> ifaceStatsMap(IFACE_STATS_MAP_PATH);
return bpfGetIfIndexStatsInternal(ifindex, stats, ifaceStatsMap);
}
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
index 4f85d9b..76c56eb 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
@@ -116,7 +116,7 @@
EXPECT_RESULT_OK(mFakeIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY));
}
- void expectStatsEqual(const StatsValue& target, const Stats& result) {
+ void expectStatsEqual(const StatsValue& target, const StatsValue& result) {
EXPECT_EQ(target.rxPackets, result.rxPackets);
EXPECT_EQ(target.rxBytes, result.rxBytes);
EXPECT_EQ(target.txPackets, result.txPackets);
@@ -194,7 +194,7 @@
.txPackets = 0,
.txBytes = 0,
};
- Stats result1 = {};
+ StatsValue result1 = {};
ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeAppUidStatsMap));
expectStatsEqual(value1, result1);
}
@@ -217,11 +217,11 @@
};
ASSERT_RESULT_OK(mFakeAppUidStatsMap.writeValue(TEST_UID1, value1, BPF_ANY));
ASSERT_RESULT_OK(mFakeAppUidStatsMap.writeValue(TEST_UID2, value2, BPF_ANY));
- Stats result1 = {};
+ StatsValue result1 = {};
ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeAppUidStatsMap));
expectStatsEqual(value1, result1);
- Stats result2 = {};
+ StatsValue result2 = {};
ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID2, &result2, mFakeAppUidStatsMap));
expectStatsEqual(value2, result2);
std::vector<stats_line> lines;
@@ -255,15 +255,15 @@
ifaceStatsKey = IFACE_INDEX3;
EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
- Stats result1 = {};
+ StatsValue result1 = {};
ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME1, &result1, mFakeIfaceStatsMap,
mFakeIfaceIndexNameMap));
expectStatsEqual(value1, result1);
- Stats result2 = {};
+ StatsValue result2 = {};
ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME2, &result2, mFakeIfaceStatsMap,
mFakeIfaceIndexNameMap));
expectStatsEqual(value2, result2);
- Stats totalResult = {};
+ StatsValue totalResult = {};
ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
mFakeIfaceIndexNameMap));
StatsValue totalValue = {
@@ -284,7 +284,7 @@
};
EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(IFACE_INDEX1, value, BPF_ANY));
- Stats result = {};
+ StatsValue result = {};
ASSERT_EQ(0, bpfGetIfIndexStatsInternal(IFACE_INDEX1, &result, mFakeIfaceStatsMap));
expectStatsEqual(value, result);
}
diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
index 0a9c012..ea068fc 100644
--- a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
+++ b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
@@ -56,14 +56,14 @@
bool operator<(const stats_line& lhs, const stats_line& rhs);
// For test only
-int bpfGetUidStatsInternal(uid_t uid, Stats* stats,
+int bpfGetUidStatsInternal(uid_t uid, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& appUidStatsMap);
// For test only
-int bpfGetIfaceStatsInternal(const char* iface, Stats* stats,
+int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
const BpfMap<uint32_t, IfaceValue>& ifaceNameMap);
// For test only
-int bpfGetIfIndexStatsInternal(uint32_t ifindex, Stats* stats,
+int bpfGetIfIndexStatsInternal(uint32_t ifindex, StatsValue* stats,
const BpfMap<uint32_t, StatsValue>& ifaceStatsMap);
// For test only
int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>& lines,
@@ -113,9 +113,9 @@
const BpfMap<uint32_t, StatsValue>& statsMap,
const BpfMap<uint32_t, IfaceValue>& ifaceMap);
-int bpfGetUidStats(uid_t uid, Stats* stats);
-int bpfGetIfaceStats(const char* iface, Stats* stats);
-int bpfGetIfIndexStats(int ifindex, Stats* stats);
+int bpfGetUidStats(uid_t uid, StatsValue* stats);
+int bpfGetIfaceStats(const char* iface, StatsValue* stats);
+int bpfGetIfIndexStats(int ifindex, StatsValue* stats);
int parseBpfNetworkStatsDetail(std::vector<stats_line>* lines);
int parseBpfNetworkStatsDev(std::vector<stats_line>* lines);
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
index 097dbe0..2ef7368 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
@@ -34,7 +34,6 @@
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.util.List;
-import java.util.Objects;
/**
* The {@link MdnsMultinetworkSocketClient} manages the multinetwork socket for mDns
@@ -49,10 +48,9 @@
@NonNull private final MdnsSocketProvider mSocketProvider;
@NonNull private final SharedLog mSharedLog;
- private final ArrayMap<MdnsServiceBrowserListener, InterfaceSocketCallback> mRequestedNetworks =
+ private final ArrayMap<MdnsServiceBrowserListener, InterfaceSocketCallback> mSocketRequests =
new ArrayMap<>();
- private final ArrayMap<MdnsInterfaceSocket, ReadPacketHandler> mSocketPacketHandlers =
- new ArrayMap<>();
+ private final ArrayMap<SocketKey, ReadPacketHandler> mSocketPacketHandlers = new ArrayMap<>();
private MdnsSocketClientBase.Callback mCallback = null;
private int mReceivedPacketNumber = 0;
@@ -68,8 +66,7 @@
@NonNull
private final SocketCreationCallback mSocketCreationCallback;
@NonNull
- private final ArrayMap<MdnsInterfaceSocket, SocketKey> mActiveSockets =
- new ArrayMap<>();
+ private final ArrayMap<SocketKey, MdnsInterfaceSocket> mActiveSockets = new ArrayMap<>();
InterfaceSocketCallback(SocketCreationCallback socketCreationCallback) {
mSocketCreationCallback = socketCreationCallback;
@@ -80,27 +77,27 @@
@NonNull MdnsInterfaceSocket socket, @NonNull List<LinkAddress> addresses) {
// The socket may be already created by other request before, try to get the stored
// ReadPacketHandler.
- ReadPacketHandler handler = mSocketPacketHandlers.get(socket);
+ ReadPacketHandler handler = mSocketPacketHandlers.get(socketKey);
if (handler == null) {
// First request to create this socket. Initial a ReadPacketHandler for this socket.
handler = new ReadPacketHandler(socketKey);
- mSocketPacketHandlers.put(socket, handler);
+ mSocketPacketHandlers.put(socketKey, handler);
}
socket.addPacketHandler(handler);
- mActiveSockets.put(socket, socketKey);
+ mActiveSockets.put(socketKey, socket);
mSocketCreationCallback.onSocketCreated(socketKey);
}
@Override
public void onInterfaceDestroyed(@NonNull SocketKey socketKey,
@NonNull MdnsInterfaceSocket socket) {
- notifySocketDestroyed(socket);
- maybeCleanupPacketHandler(socket);
+ notifySocketDestroyed(socketKey);
+ maybeCleanupPacketHandler(socketKey);
}
- private void notifySocketDestroyed(@NonNull MdnsInterfaceSocket socket) {
- final SocketKey socketKey = mActiveSockets.remove(socket);
- if (!isSocketActive(socket)) {
+ private void notifySocketDestroyed(@NonNull SocketKey socketKey) {
+ mActiveSockets.remove(socketKey);
+ if (!isSocketActive(socketKey)) {
mSocketCreationCallback.onSocketDestroyed(socketKey);
}
}
@@ -108,35 +105,38 @@
void onNetworkUnrequested() {
for (int i = mActiveSockets.size() - 1; i >= 0; i--) {
// Iterate from the end so the socket can be removed
- final MdnsInterfaceSocket socket = mActiveSockets.keyAt(i);
- notifySocketDestroyed(socket);
- maybeCleanupPacketHandler(socket);
+ final SocketKey socketKey = mActiveSockets.keyAt(i);
+ notifySocketDestroyed(socketKey);
+ maybeCleanupPacketHandler(socketKey);
}
}
}
- private boolean isSocketActive(@NonNull MdnsInterfaceSocket socket) {
- for (int i = 0; i < mRequestedNetworks.size(); i++) {
- final InterfaceSocketCallback isc = mRequestedNetworks.valueAt(i);
- if (isc.mActiveSockets.containsKey(socket)) {
+ private boolean isSocketActive(@NonNull SocketKey socketKey) {
+ for (int i = 0; i < mSocketRequests.size(); i++) {
+ final InterfaceSocketCallback ifaceSocketCallback = mSocketRequests.valueAt(i);
+ if (ifaceSocketCallback.mActiveSockets.containsKey(socketKey)) {
return true;
}
}
return false;
}
- private ArrayMap<MdnsInterfaceSocket, SocketKey> getActiveSockets() {
- final ArrayMap<MdnsInterfaceSocket, SocketKey> sockets = new ArrayMap<>();
- for (int i = 0; i < mRequestedNetworks.size(); i++) {
- final InterfaceSocketCallback isc = mRequestedNetworks.valueAt(i);
- sockets.putAll(isc.mActiveSockets);
+ @Nullable
+ private MdnsInterfaceSocket getTargetSocket(@NonNull SocketKey targetSocketKey) {
+ for (int i = 0; i < mSocketRequests.size(); i++) {
+ final InterfaceSocketCallback ifaceSocketCallback = mSocketRequests.valueAt(i);
+ final int index = ifaceSocketCallback.mActiveSockets.indexOfKey(targetSocketKey);
+ if (index >= 0) {
+ return ifaceSocketCallback.mActiveSockets.valueAt(index);
+ }
}
- return sockets;
+ return null;
}
- private void maybeCleanupPacketHandler(@NonNull MdnsInterfaceSocket socket) {
- if (isSocketActive(socket)) return;
- mSocketPacketHandlers.remove(socket);
+ private void maybeCleanupPacketHandler(@NonNull SocketKey socketKey) {
+ if (isSocketActive(socketKey)) return;
+ mSocketPacketHandlers.remove(socketKey);
}
private class ReadPacketHandler implements MulticastPacketReader.PacketHandler {
@@ -171,14 +171,14 @@
public void notifyNetworkRequested(@NonNull MdnsServiceBrowserListener listener,
@Nullable Network network, @NonNull SocketCreationCallback socketCreationCallback) {
ensureRunningOnHandlerThread(mHandler);
- InterfaceSocketCallback callback = mRequestedNetworks.get(listener);
+ InterfaceSocketCallback callback = mSocketRequests.get(listener);
if (callback != null) {
throw new IllegalArgumentException("Can not register duplicated listener");
}
if (DBG) mSharedLog.v("notifyNetworkRequested: network=" + network);
callback = new InterfaceSocketCallback(socketCreationCallback);
- mRequestedNetworks.put(listener, callback);
+ mSocketRequests.put(listener, callback);
mSocketProvider.requestSocket(network, callback);
}
@@ -186,14 +186,14 @@
@Override
public void notifyNetworkUnrequested(@NonNull MdnsServiceBrowserListener listener) {
ensureRunningOnHandlerThread(mHandler);
- final InterfaceSocketCallback callback = mRequestedNetworks.get(listener);
+ final InterfaceSocketCallback callback = mSocketRequests.get(listener);
if (callback == null) {
mSharedLog.e("Can not be unrequested with unknown listener=" + listener);
return;
}
callback.onNetworkUnrequested();
- // onNetworkUnrequested does cleanups based on mRequestedNetworks, only remove afterwards
- mRequestedNetworks.remove(listener);
+ // onNetworkUnrequested does cleanups based on mSocketRequests, only remove afterwards
+ mSocketRequests.remove(listener);
mSocketProvider.unrequestSocket(callback);
}
@@ -209,42 +209,28 @@
private void sendMdnsPacket(@NonNull DatagramPacket packet, @NonNull SocketKey targetSocketKey,
boolean onlyUseIpv6OnIpv6OnlyNetworks) {
+ final MdnsInterfaceSocket socket = getTargetSocket(targetSocketKey);
+ if (socket == null) {
+ mSharedLog.e("No socket matches targetSocketKey=" + targetSocketKey);
+ return;
+ }
+
final boolean isIpv6 = ((InetSocketAddress) packet.getSocketAddress()).getAddress()
instanceof Inet6Address;
final boolean isIpv4 = ((InetSocketAddress) packet.getSocketAddress()).getAddress()
instanceof Inet4Address;
- final ArrayMap<MdnsInterfaceSocket, SocketKey> activeSockets = getActiveSockets();
- boolean shouldQueryIpv6 = !onlyUseIpv6OnIpv6OnlyNetworks || isIpv6OnlySockets(
- activeSockets, targetSocketKey);
- for (int i = 0; i < activeSockets.size(); i++) {
- final MdnsInterfaceSocket socket = activeSockets.keyAt(i);
- final SocketKey socketKey = activeSockets.valueAt(i);
- // Check ip capability and network before sending packet
- if (((isIpv6 && socket.hasJoinedIpv6() && shouldQueryIpv6)
- || (isIpv4 && socket.hasJoinedIpv4()))
- && Objects.equals(socketKey, targetSocketKey)) {
- try {
- socket.send(packet);
- } catch (IOException e) {
- mSharedLog.e("Failed to send a mDNS packet.", e);
- }
+ final boolean shouldQueryIpv6 = !onlyUseIpv6OnIpv6OnlyNetworks || !socket.hasJoinedIpv4();
+ // Check ip capability and network before sending packet
+ if ((isIpv6 && socket.hasJoinedIpv6() && shouldQueryIpv6)
+ || (isIpv4 && socket.hasJoinedIpv4())) {
+ try {
+ socket.send(packet);
+ } catch (IOException e) {
+ mSharedLog.e("Failed to send a mDNS packet.", e);
}
}
}
- private boolean isIpv6OnlySockets(
- @NonNull ArrayMap<MdnsInterfaceSocket, SocketKey> activeSockets,
- @NonNull SocketKey targetSocketKey) {
- for (int i = 0; i < activeSockets.size(); i++) {
- final MdnsInterfaceSocket socket = activeSockets.keyAt(i);
- final SocketKey socketKey = activeSockets.valueAt(i);
- if (Objects.equals(socketKey, targetSocketKey) && socket.hasJoinedIpv4()) {
- return false;
- }
- }
- return true;
- }
-
private void processResponsePacket(byte[] recvbuf, int length, @NonNull SocketKey socketKey) {
int packetNumber = ++mReceivedPacketNumber;
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 7aff6a4..2842cc3 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -43,7 +43,6 @@
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
-import android.provider.DeviceConfig;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArraySet;
@@ -95,8 +94,8 @@
private static boolean sInitialized = false;
private static Boolean sEnableJavaBpfMap = null;
- private static final String BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP =
- "bpf_net_maps_enable_java_bpf_map";
+ private static final String BPF_NET_MAPS_FORCE_DISABLE_JAVA_BPF_MAP =
+ "bpf_net_maps_force_disable_java_bpf_map";
// Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY.
// This entry is not accessed by others.
@@ -283,9 +282,8 @@
if (sInitialized) return;
if (sEnableJavaBpfMap == null) {
sEnableJavaBpfMap = SdkLevel.isAtLeastU() ||
- DeviceConfigUtils.isFeatureEnabled(context,
- DeviceConfig.NAMESPACE_TETHERING, BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP,
- DeviceConfigUtils.TETHERING_MODULE_NAME, false /* defaultValue */);
+ DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ BPF_NET_MAPS_FORCE_DISABLE_JAVA_BPF_MAP);
}
Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
@@ -1143,7 +1141,7 @@
}
}
- @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private static native void native_init(boolean startSkDestroyListener);
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
diff --git a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
index 4f2909c..3befcfa 100644
--- a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
@@ -20,7 +20,6 @@
import static android.net.SocketKeepalive.MIN_INTERVAL_SEC;
import static android.net.SocketKeepalive.SUCCESS;
import static android.net.SocketKeepalive.SUCCESS_PAUSED;
-import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.SOL_SOCKET;
@@ -92,8 +91,8 @@
private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET6, AF_INET};
private static final long LOW_TCP_POLLING_INTERVAL_MS = 1_000L;
private static final int ADJUST_TCP_POLLING_DELAY_MS = 2000;
- private static final String AUTOMATIC_ON_OFF_KEEPALIVE_VERSION =
- "automatic_on_off_keepalive_version";
+ private static final String AUTOMATIC_ON_OFF_KEEPALIVE_DISABLE_FLAG =
+ "automatic_on_off_keepalive_disable_flag";
public static final long METRICS_COLLECTION_DURATION_MS = 24 * 60 * 60 * 1_000L;
// ConnectivityService parses message constants from itself and AutomaticOnOffKeepaliveTracker
@@ -219,8 +218,8 @@
// Reading DeviceConfig will check if the calling uid and calling package name are the
// same. Clear calling identity to align the calling uid and package
final boolean enabled = BinderUtils.withCleanCallingIdentity(
- () -> mDependencies.isFeatureEnabled(AUTOMATIC_ON_OFF_KEEPALIVE_VERSION,
- true /* defaultEnabled */));
+ () -> mDependencies.isTetheringFeatureNotChickenedOut(
+ AUTOMATIC_ON_OFF_KEEPALIVE_DISABLE_FLAG));
if (autoOnOff && enabled) {
mAutomaticOnOffState = STATE_ENABLED;
if (null == ki.mFd) {
@@ -700,8 +699,8 @@
// Clear calling identity to align the calling uid and package so that it won't fail if cts
// would like to call dump()
final boolean featureEnabled = BinderUtils.withCleanCallingIdentity(
- () -> mDependencies.isFeatureEnabled(AUTOMATIC_ON_OFF_KEEPALIVE_VERSION,
- true /* defaultEnabled */));
+ () -> mDependencies.isTetheringFeatureNotChickenedOut(
+ AUTOMATIC_ON_OFF_KEEPALIVE_DISABLE_FLAG));
pw.println("AutomaticOnOff enabled: " + featureEnabled);
pw.increaseIndent();
for (AutomaticOnOffKeepalive autoKi : mAutomaticOnOffKeepalives) {
@@ -969,16 +968,13 @@
}
/**
- * Find out if a feature is enabled from DeviceConfig.
+ * Find out if a feature is not disabled from DeviceConfig.
*
* @param name The name of the property to look up.
- * @param defaultEnabled whether to consider the feature enabled in the absence of
- * the flag. This MUST be a statically-known constant.
* @return whether the feature is enabled
*/
- public boolean isFeatureEnabled(@NonNull final String name, final boolean defaultEnabled) {
- return DeviceConfigUtils.isFeatureEnabled(mContext, NAMESPACE_TETHERING, name,
- DeviceConfigUtils.TETHERING_MODULE_NAME, defaultEnabled);
+ public boolean isTetheringFeatureNotChickenedOut(@NonNull final String name) {
+ return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(name);
}
/**
diff --git a/service/src/com/android/server/connectivity/KeepaliveTracker.java b/service/src/com/android/server/connectivity/KeepaliveTracker.java
index ae70767..feba821 100644
--- a/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveTracker.java
@@ -993,7 +993,7 @@
*/
public boolean isAddressTranslationEnabled(@NonNull Context context) {
return DeviceConfigUtils.isFeatureSupported(context, FEATURE_CLAT_ADDRESS_TRANSLATE)
- && !DeviceConfigUtils.isTetheringFeatureForceDisabled(
+ && DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
CONFIG_DISABLE_CLAT_ADDRESS_TRANSLATE);
}
}
diff --git a/tests/cts/net/native/dns/Android.bp b/tests/cts/net/native/dns/Android.bp
index 2469710..da4fe28 100644
--- a/tests/cts/net/native/dns/Android.bp
+++ b/tests/cts/net/native/dns/Android.bp
@@ -30,6 +30,7 @@
],
// To be compatible with R devices, the min_sdk_version must be 30.
min_sdk_version: "30",
+ host_required: ["net-tests-utils-host-common"],
}
cc_test {
diff --git a/tests/cts/net/native/dns/AndroidTest.xml b/tests/cts/net/native/dns/AndroidTest.xml
index 6d03c23..d49696b 100644
--- a/tests/cts/net/native/dns/AndroidTest.xml
+++ b/tests/cts/net/native/dns/AndroidTest.xml
@@ -24,6 +24,8 @@
<option name="push" value="CtsNativeNetDnsTestCases->/data/local/tmp/CtsNativeNetDnsTestCases" />
<option name="append-bitness" value="true" />
</target_preparer>
+ <target_preparer class="com.android.testutils.ConnectivityTestTargetPreparer">
+ </target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="CtsNativeNetDnsTestCases" />
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index e978664..bce08df 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -2744,7 +2744,6 @@
*/
@AppModeFull(reason = "Instant apps cannot create test networks")
@Test
- @SkipMainlinePresubmit(reason = "Out of SLO flakiness")
public void testSetOemNetworkPreferenceForTestOnlyPref() throws Exception {
// Cannot use @IgnoreUpTo(Build.VERSION_CODES.R) because this test also requires API 31
// shims, and @IgnoreUpTo does not check that.
@@ -2757,17 +2756,19 @@
final TestableNetworkCallback systemDefaultCallback = new TestableNetworkCallback();
final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
+ final Network testNetwork = tnt.getNetwork();
testAndCleanup(() -> {
setOemNetworkPreferenceForMyPackage(
OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY);
registerTestOemNetworkPreferenceCallbacks(defaultCallback, systemDefaultCallback);
- waitForAvailable(defaultCallback, tnt.getNetwork());
+ waitForAvailable(defaultCallback, testNetwork);
systemDefaultCallback.eventuallyExpect(CallbackEntry.AVAILABLE,
NETWORK_CALLBACK_TIMEOUT_MS, cb -> wifiNetwork.equals(cb.getNetwork()));
}, /* cleanup */ () -> {
runWithShellPermissionIdentity(tnt::teardown);
- defaultCallback.expect(CallbackEntry.LOST, tnt, NETWORK_CALLBACK_TIMEOUT_MS);
+ defaultCallback.eventuallyExpect(CallbackEntry.LOST, NETWORK_CALLBACK_TIMEOUT_MS,
+ cb -> testNetwork.equals(cb.getNetwork()));
// This network preference should only ever use the test network therefore available
// should not trigger when the test network goes down (e.g. switch to cellular).
@@ -3205,7 +3206,6 @@
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
- @SkipPresubmit(reason = "Out of SLO flakiness")
public void testMobileDataPreferredUids() throws Exception {
assumeTrue(TestUtils.shouldTestSApis());
final boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
diff --git a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
index 81834a9..805dd65 100644
--- a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
@@ -71,8 +71,6 @@
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.RecorderCallback.CallbackEntry;
-import com.android.testutils.SkipMainlinePresubmit;
-import com.android.testutils.SkipPresubmit;
import com.android.testutils.TestableNetworkCallback;
import org.bouncycastle.x509.X509V1CertificateGenerator;
@@ -642,7 +640,6 @@
}
@Test
- @SkipMainlinePresubmit(reason = "Out of SLO flakiness")
public void testStartStopVpnProfileV4() throws Exception {
doTestStartStopVpnProfile(false /* testIpv6Only */, false /* requiresValidation */,
false /* testSessionKey */, false /* testIkeTunConnParams */);
@@ -656,14 +653,12 @@
}
@Test
- @SkipMainlinePresubmit(reason = "Out of SLO flakiness")
public void testStartStopVpnProfileV6() throws Exception {
doTestStartStopVpnProfile(true /* testIpv6Only */, false /* requiresValidation */,
false /* testSessionKey */, false /* testIkeTunConnParams */);
}
@Test @IgnoreUpTo(SC_V2)
- @SkipPresubmit(reason = "Out of SLO flakiness")
public void testStartStopVpnProfileV6WithValidation() throws Exception {
assumeTrue(TestUtils.shouldTestTApis());
doTestStartStopVpnProfile(true /* testIpv6Only */, true /* requiresValidation */,
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index e4ee8de..7be4f78 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -25,6 +25,7 @@
import android.net.LinkProperties
import android.net.LocalSocket
import android.net.LocalSocketAddress
+import android.net.MacAddress
import android.net.Network
import android.net.NetworkAgentConfig
import android.net.NetworkCapabilities
@@ -73,6 +74,8 @@
import android.system.OsConstants.AF_INET6
import android.system.OsConstants.EADDRNOTAVAIL
import android.system.OsConstants.ENETUNREACH
+import android.system.OsConstants.ETH_P_IPV6
+import android.system.OsConstants.IPPROTO_IPV6
import android.system.OsConstants.IPPROTO_UDP
import android.system.OsConstants.SOCK_DGRAM
import android.util.Log
@@ -82,13 +85,21 @@
import com.android.compatibility.common.util.PropertyUtil
import com.android.modules.utils.build.SdkLevel.isAtLeastU
import com.android.net.module.util.ArrayTrackRecord
+import com.android.net.module.util.DnsPacket
+import com.android.net.module.util.HexDump
+import com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN
+import com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN
+import com.android.net.module.util.NetworkStackConstants.UDP_HEADER_LEN
+import com.android.net.module.util.PacketBuilder
import com.android.net.module.util.TrackRecord
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.IPv6UdpFilter
import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
+import com.android.testutils.TapPacketReader
import com.android.testutils.TestableNetworkAgent
import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
import com.android.testutils.TestableNetworkCallback
@@ -103,6 +114,7 @@
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.ServerSocket
+import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
import java.util.Random
import java.util.concurrent.Executor
@@ -133,6 +145,8 @@
private const val REGISTRATION_TIMEOUT_MS = 10_000L
private const val DBG = false
private const val TEST_PORT = 12345
+private const val MDNS_PORT = 5353.toShort()
+private val multicastIpv6Addr = parseNumericAddress("ff02::fb") as Inet6Address
@AppModeFull(reason = "Socket cannot bind in instant app mode")
@RunWith(DevSdkIgnoreRunner::class)
@@ -194,8 +208,8 @@
inline fun <reified V : NsdEvent> expectCallback(timeoutMs: Long = TIMEOUT_MS): V {
val nextEvent = nextEvents.poll(timeoutMs)
- assertNotNull(nextEvent, "No callback received after $timeoutMs ms, expected " +
- "${V::class.java.simpleName}")
+ assertNotNull(nextEvent, "No callback received after $timeoutMs ms, " +
+ "expected ${V::class.java.simpleName}")
assertTrue(nextEvent is V, "Expected ${V::class.java.simpleName} but got " +
nextEvent.javaClass.simpleName)
return nextEvent
@@ -411,7 +425,6 @@
val lp = LinkProperties().apply {
interfaceName = ifaceName
}
-
val agent = TestableNetworkAgent(context, handlerThread.looper,
NetworkCapabilities().apply {
removeCapability(NET_CAPABILITY_TRUSTED)
@@ -1144,6 +1157,176 @@
}
}
+ @Test
+ fun testRegisterWithConflictDuringProbing() {
+ // This test requires shims supporting T+ APIs (NsdServiceInfo.network)
+ assumeTrue(TestUtils.shouldTestTApis())
+
+ val si = NsdServiceInfo()
+ si.serviceType = serviceType
+ si.serviceName = serviceName
+ si.network = testNetwork1.network
+ si.port = 12345 // Test won't try to connect so port does not matter
+
+ val packetReader = TapPacketReader(Handler(handlerThread.looper),
+ testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
+ packetReader.startAsyncForTest()
+ handlerThread.waitForIdle(TIMEOUT_MS)
+
+ // Register service on testNetwork1
+ val registrationRecord = NsdRegistrationRecord()
+ nsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, { it.run() },
+ registrationRecord)
+
+ tryTest {
+ assertNotNull(packetReader.pollForProbe(serviceName, serviceType),
+ "Did not find a probe for the service")
+ packetReader.sendResponse(buildConflictingAnnouncement())
+
+ // Registration must use an updated name to avoid the conflict
+ val cb = registrationRecord.expectCallback<ServiceRegistered>(REGISTRATION_TIMEOUT_MS)
+ cb.serviceInfo.serviceName.let {
+ assertTrue("Unexpected registered name: $it",
+ it.startsWith(serviceName) && it != serviceName)
+ }
+ } cleanupStep {
+ nsdManager.unregisterService(registrationRecord)
+ registrationRecord.expectCallback<ServiceUnregistered>()
+ } cleanup {
+ packetReader.handler.post { packetReader.stop() }
+ handlerThread.waitForIdle(TIMEOUT_MS)
+ }
+ }
+
+ @Test
+ fun testRegisterWithConflictAfterProbing() {
+ // This test requires shims supporting T+ APIs (NsdServiceInfo.network)
+ assumeTrue(TestUtils.shouldTestTApis())
+
+ val si = NsdServiceInfo()
+ si.serviceType = serviceType
+ si.serviceName = serviceName
+ si.network = testNetwork1.network
+ si.port = 12345 // Test won't try to connect so port does not matter
+
+ // Register service on testNetwork1
+ val registrationRecord = NsdRegistrationRecord()
+ val discoveryRecord = NsdDiscoveryRecord()
+ val registeredService = registerService(registrationRecord, si)
+ val packetReader = TapPacketReader(Handler(handlerThread.looper),
+ testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
+ packetReader.startAsyncForTest()
+ handlerThread.waitForIdle(TIMEOUT_MS)
+
+ tryTest {
+ assertNotNull(packetReader.pollForAdvertisement(serviceName, serviceType),
+ "No announcements sent after initial probing")
+
+ assertEquals(si.serviceName, registeredService.serviceName)
+
+ nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD,
+ testNetwork1.network, { it.run() }, discoveryRecord)
+ discoveryRecord.waitForServiceDiscovered(si.serviceName, serviceType)
+
+ // Send a conflicting announcement
+ val conflictingAnnouncement = buildConflictingAnnouncement()
+ packetReader.sendResponse(conflictingAnnouncement)
+
+ // Expect to see probes (RFC6762 9., service is reset to probing state)
+ assertNotNull(packetReader.pollForProbe(serviceName, serviceType),
+ "Probe not received within timeout after conflict")
+
+ // Send the conflicting packet again to reply to the probe
+ packetReader.sendResponse(conflictingAnnouncement)
+
+ // Note the legacy mdnsresponder would send an exit announcement here (a 0-lifetime
+ // advertisement just for the PTR record), but not the new advertiser. This probably
+ // follows RFC 6762 8.4, saying that when a record rdata changed, "In the case of shared
+ // records, a host MUST send a "goodbye" announcement with RR TTL zero [...] for the old
+ // rdata, to cause it to be deleted from peer caches, before announcing the new rdata".
+ //
+ // This should be implemented by the new advertiser, but in the case of conflicts it is
+ // not very valuable since an identical PTR record would be used by the conflicting
+ // service (except for subtypes). In that case the exit announcement may be
+ // counter-productive as it conflicts with announcements done by the conflicting
+ // service.
+
+ // Note that before sending the following ServiceRegistered callback for the renamed
+ // service, the legacy mdnsresponder-based implementation would first send a
+ // Service*Registered* callback for the original service name being *unregistered*; it
+ // should have been a ServiceUnregistered callback instead (bug in NsdService
+ // interpretation of the callback).
+ val newRegistration = registrationRecord.expectCallbackEventually<ServiceRegistered>(
+ REGISTRATION_TIMEOUT_MS) {
+ it.serviceInfo.serviceName.startsWith(serviceName) &&
+ it.serviceInfo.serviceName != serviceName
+ }
+
+ discoveryRecord.expectCallbackEventually<ServiceFound> {
+ it.serviceInfo.serviceName == newRegistration.serviceInfo.serviceName
+ }
+ } cleanupStep {
+ nsdManager.stopServiceDiscovery(discoveryRecord)
+ discoveryRecord.expectCallback<DiscoveryStopped>()
+ } cleanupStep {
+ nsdManager.unregisterService(registrationRecord)
+ registrationRecord.expectCallback<ServiceUnregistered>()
+ } cleanup {
+ packetReader.handler.post { packetReader.stop() }
+ handlerThread.waitForIdle(TIMEOUT_MS)
+ }
+ }
+
+ private fun buildConflictingAnnouncement(): ByteBuffer {
+ /*
+ Generated with:
+ scapy.raw(scapy.DNS(rd=0, qr=1, aa=1, qd = None, an =
+ scapy.DNSRRSRV(rrname='NsdTest123456789._nmt123456789._tcp.local',
+ rclass=0x8001, port=31234, target='conflict.local', ttl=120)
+ )).hex()
+ */
+ val mdnsPayload = HexDump.hexStringToByteArray("000084000000000100000000104e736454657" +
+ "3743132333435363738390d5f6e6d74313233343536373839045f746370056c6f63616c00002" +
+ "18001000000780016000000007a0208636f6e666c696374056c6f63616c00")
+ val packetBuffer = ByteBuffer.wrap(mdnsPayload)
+ // Replace service name and types in the packet with the random ones used in the test.
+ // Test service name and types have consistent length and are always ASCII
+ val testPacketName = "NsdTest123456789".encodeToByteArray()
+ val testPacketTypePrefix = "_nmt123456789".encodeToByteArray()
+ val encodedServiceName = serviceName.encodeToByteArray()
+ val encodedTypePrefix = serviceType.split('.')[0].encodeToByteArray()
+ assertEquals(testPacketName.size, encodedServiceName.size)
+ assertEquals(testPacketTypePrefix.size, encodedTypePrefix.size)
+ packetBuffer.position(mdnsPayload.indexOf(testPacketName))
+ packetBuffer.put(encodedServiceName)
+ packetBuffer.position(mdnsPayload.indexOf(testPacketTypePrefix))
+ packetBuffer.put(encodedTypePrefix)
+
+ return buildMdnsPacket(mdnsPayload)
+ }
+
+ private fun buildMdnsPacket(mdnsPayload: ByteArray): ByteBuffer {
+ val packetBuffer = PacketBuilder.allocate(true /* hasEther */, IPPROTO_IPV6,
+ IPPROTO_UDP, mdnsPayload.size)
+ val packetBuilder = PacketBuilder(packetBuffer)
+ // Multicast ethernet address for IPv6 to ff02::fb
+ val multicastEthAddr = MacAddress.fromBytes(
+ byteArrayOf(0x33, 0x33, 0, 0, 0, 0xfb.toByte()))
+ packetBuilder.writeL2Header(
+ MacAddress.fromBytes(byteArrayOf(1, 2, 3, 4, 5, 6)) /* srcMac */,
+ multicastEthAddr,
+ ETH_P_IPV6.toShort())
+ packetBuilder.writeIpv6Header(
+ 0x60000000, // version=6, traffic class=0x0, flowlabel=0x0
+ IPPROTO_UDP.toByte(),
+ 64 /* hop limit */,
+ parseNumericAddress("2001:db8::123") as Inet6Address /* srcIp */,
+ multicastIpv6Addr /* dstIp */)
+ packetBuilder.writeUdpHeader(MDNS_PORT /* srcPort */, MDNS_PORT /* dstPort */)
+ packetBuffer.put(mdnsPayload)
+ return packetBuilder.finalizePacket()
+ }
+
/**
* Register a service and return its registration record.
*/
@@ -1169,7 +1352,65 @@
}
}
+private fun TapPacketReader.pollForMdnsPacket(
+ timeoutMs: Long = REGISTRATION_TIMEOUT_MS,
+ predicate: (TestDnsPacket) -> Boolean
+): ByteArray? {
+ val mdnsProbeFilter = IPv6UdpFilter(srcPort = MDNS_PORT, dstPort = MDNS_PORT).and {
+ val mdnsPayload = it.copyOfRange(
+ ETHER_HEADER_LEN + IPV6_HEADER_LEN + UDP_HEADER_LEN, it.size)
+ try {
+ predicate(TestDnsPacket(mdnsPayload))
+ } catch (e: DnsPacket.ParseException) {
+ false
+ }
+ }
+ return poll(timeoutMs, mdnsProbeFilter)
+}
+
+private fun TapPacketReader.pollForProbe(
+ serviceName: String,
+ serviceType: String,
+ timeoutMs: Long = REGISTRATION_TIMEOUT_MS
+): ByteArray? = pollForMdnsPacket(timeoutMs) { it.isProbeFor("$serviceName.$serviceType.local") }
+
+private fun TapPacketReader.pollForAdvertisement(
+ serviceName: String,
+ serviceType: String,
+ timeoutMs: Long = REGISTRATION_TIMEOUT_MS
+): ByteArray? = pollForMdnsPacket(timeoutMs) { it.isReplyFor("$serviceName.$serviceType.local") }
+
+private class TestDnsPacket(data: ByteArray) : DnsPacket(data) {
+ fun isProbeFor(name: String): Boolean = mRecords[QDSECTION].any {
+ it.dName == name && it.nsType == 0xff /* ANY */
+ }
+
+ fun isReplyFor(name: String): Boolean = mRecords[ANSECTION].any {
+ it.dName == name && it.nsType == 0x21 /* SRV */
+ }
+}
+
private fun ByteArray?.utf8ToString(): String {
if (this == null) return ""
return String(this, StandardCharsets.UTF_8)
}
+
+private fun ByteArray.indexOf(sub: ByteArray): Int {
+ var subIndex = 0
+ forEachIndexed { i, b ->
+ when (b) {
+ // Still matching: continue comparing with next byte
+ sub[subIndex] -> {
+ subIndex++
+ if (subIndex == sub.size) {
+ return i - sub.size + 1
+ }
+ }
+ // Not matching next byte but matches first byte: continue comparing with 2nd byte
+ sub[0] -> subIndex = 1
+ // No matches: continue comparing from first byte
+ else -> subIndex = 0
+ }
+ }
+ return -1
+}
diff --git a/tests/cts/net/src/android/net/cts/TestNetworkRunnable.java b/tests/cts/net/src/android/net/cts/TestNetworkRunnable.java
index 0eb5644..1b22f42 100644
--- a/tests/cts/net/src/android/net/cts/TestNetworkRunnable.java
+++ b/tests/cts/net/src/android/net/cts/TestNetworkRunnable.java
@@ -95,14 +95,17 @@
testIface.getFileDescriptor().close();
}
- if (tunNetworkCallback != null) {
- sCm.unregisterNetworkCallback(tunNetworkCallback);
- }
final Network testNetwork = tunNetworkCallback.currentNetwork;
if (testNetwork != null) {
tnm.teardownTestNetwork(testNetwork);
}
+ // Ensure test network being torn down.
+ tunNetworkCallback.waitForLost();
+
+ if (tunNetworkCallback != null) {
+ sCm.unregisterNetworkCallback(tunNetworkCallback);
+ }
}
}
diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp
index c294e7b..442d69f 100644
--- a/tests/mts/bpf_existence_test.cpp
+++ b/tests/mts/bpf_existence_test.cpp
@@ -33,6 +33,8 @@
using android::modules::sdklevel::IsAtLeastR;
using android::modules::sdklevel::IsAtLeastS;
using android::modules::sdklevel::IsAtLeastT;
+using android::modules::sdklevel::IsAtLeastU;
+using android::modules::sdklevel::IsAtLeastV;
#define PLATFORM "/sys/fs/bpf/"
#define TETHERING "/sys/fs/bpf/tethering/"
@@ -147,10 +149,14 @@
// so we should only test for the removal of stuff that was mainline'd,
// and for the presence of mainline stuff.
+ // Note: Q is no longer supported by mainline
+ ASSERT_TRUE(IsAtLeastR());
+
// R can potentially run on pre-4.9 kernel non-eBPF capable devices.
DO_EXPECT(IsAtLeastR() && !IsAtLeastS() && isAtLeastKernelVersion(4, 9, 0), PLATFORM_ONLY_IN_R);
// S requires Linux Kernel 4.9+ and thus requires eBPF support.
+ if (IsAtLeastS()) ASSERT_TRUE(isAtLeastKernelVersion(4, 9, 0));
DO_EXPECT(IsAtLeastS(), MAINLINE_FOR_S_PLUS);
DO_EXPECT(IsAtLeastS() && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_S_5_10_PLUS);
@@ -163,6 +169,10 @@
DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_T_5_15_PLUS);
// U requires Linux Kernel 4.14+, but nothing (as yet) added or removed in U.
+ if (IsAtLeastU()) ASSERT_TRUE(isAtLeastKernelVersion(4, 14, 0));
+
+ // V requires Linux Kernel 4.19+, but nothing (as yet) added or removed in V.
+ if (IsAtLeastV()) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0));
for (const auto& file : mustExist) {
EXPECT_EQ(0, access(file.c_str(), R_OK)) << file << " does not exist";
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 3688d83..708697c 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -2301,7 +2301,7 @@
}
@Override
- public boolean isFeatureEnabled(@NonNull final String name, final boolean defaultEnabled) {
+ public boolean isTetheringFeatureNotChickenedOut(@NonNull final String name) {
// Tests for enabling the feature are verified in AutomaticOnOffKeepaliveTrackerTest.
// Assuming enabled here to focus on ConnectivityService tests.
return true;
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index c715c8e..dbd4e4e 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -236,8 +236,8 @@
@After
public void tearDown() throws Exception {
if (mThread != null) {
- mThread.quit();
- mThread = null;
+ mThread.quitSafely();
+ mThread.join();
}
}
diff --git a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
index b69b042..986c389 100644
--- a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
@@ -32,7 +32,6 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.longThat;
@@ -359,7 +358,7 @@
.when(mDependencies)
.newKeepaliveStatsTracker(mCtx, mTestHandler);
- doReturn(true).when(mDependencies).isFeatureEnabled(any(), anyBoolean());
+ doReturn(true).when(mDependencies).isTetheringFeatureNotChickenedOut(any());
doReturn(0L).when(mDependencies).getElapsedRealtime();
mAOOKeepaliveTracker =
new AutomaticOnOffKeepaliveTracker(mCtx, mTestHandler, mDependencies);
@@ -368,6 +367,10 @@
@After
public void teardown() throws Exception {
TestKeepaliveInfo.closeAllSockets();
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ mHandlerThread.join();
+ }
}
private final class AOOTestHandler extends Handler {
diff --git a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
index fa703eb..90a0edd 100644
--- a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
@@ -67,6 +67,7 @@
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.HandlerUtils;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -240,6 +241,14 @@
HandlerUtils.waitForIdle(mTestHandler, TIMEOUT_MS);
}
+ @After
+ public void tearDown() throws Exception {
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ mHandlerThread.join();
+ }
+ }
+
private void setElapsedRealtime(long time) {
doReturn(time).when(mDependencies).getElapsedRealtime();
}
diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
index 8dcfffa..5bde31a 100644
--- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -100,6 +100,7 @@
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.HandlerUtils;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -214,6 +215,14 @@
onUserAdded(MOCK_USER1);
}
+ @After
+ public void tearDown() throws Exception {
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ mHandlerThread.join();
+ }
+ }
+
private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion,
String packageName, int uid, String... permissions) {
final PackageInfo packageInfo =
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketProviderTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketProviderTest.java
index c0b74e1..1cc9985 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketProviderTest.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketProviderTest.java
@@ -78,6 +78,7 @@
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.HandlerUtils;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -119,6 +120,7 @@
@Mock private NetworkInterfaceWrapper mLocalOnlyIfaceWrapper;
@Mock private NetworkInterfaceWrapper mTetheredIfaceWrapper;
@Mock private SocketRequestMonitor mSocketRequestMonitor;
+ private HandlerThread mHandlerThread;
private Handler mHandler;
private MdnsSocketProvider mSocketProvider;
private NetworkCallback mNetworkCallback;
@@ -157,9 +159,9 @@
eq(TETHERED_IFACE_NAME), any());
doReturn(789).when(mDeps).getNetworkInterfaceIndexByName(
eq(WIFI_P2P_IFACE_NAME), any());
- final HandlerThread thread = new HandlerThread("MdnsSocketProviderTest");
- thread.start();
- mHandler = new Handler(thread.getLooper());
+ mHandlerThread = new HandlerThread("MdnsSocketProviderTest");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
doReturn(mTestSocketNetLinkMonitor).when(mDeps).createSocketNetlinkMonitor(any(), any(),
any());
@@ -170,10 +172,18 @@
return mTestSocketNetLinkMonitor;
}).when(mDeps).createSocketNetlinkMonitor(any(), any(),
any());
- mSocketProvider = new MdnsSocketProvider(mContext, thread.getLooper(), mDeps, mLog,
+ mSocketProvider = new MdnsSocketProvider(mContext, mHandlerThread.getLooper(), mDeps, mLog,
mSocketRequestMonitor);
}
+ @After
+ public void tearDown() throws Exception {
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ mHandlerThread.join();
+ }
+ }
+
private void runOnHandler(Runnable r) {
mHandler.post(r);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);