Merge "Fix fd leak in clatStart() by closing in finally block" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 375397b..4cf93a8 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -77,18 +77,6 @@
"name": "libnetworkstats_test"
},
{
- "name": "NetHttpCoverageTests",
- "options": [
- {
- "exclude-annotation": "com.android.testutils.SkipPresubmit"
- },
- {
- // These sometimes take longer than 1 min which is the presubmit timeout
- "exclude-annotation": "androidx.test.filters.LargeTest"
- }
- ]
- },
- {
"name": "CtsTetheringTestLatestSdk",
"options": [
{
diff --git a/netbpfload/NetBpfLoad.cpp b/netbpfload/NetBpfLoad.cpp
index 59986d4..f42e8a5 100644
--- a/netbpfload/NetBpfLoad.cpp
+++ b/netbpfload/NetBpfLoad.cpp
@@ -54,6 +54,7 @@
namespace android {
namespace bpf {
+using base::StartsWith;
using base::EndsWith;
using std::string;
@@ -228,6 +229,30 @@
return !access("/metadata/gsi/dsu/booted", F_OK);
}
+static bool hasGSM() {
+ static string ph = base::GetProperty("gsm.current.phone-type", "");
+ static bool gsm = (ph != "");
+ static bool logged = false;
+ if (!logged) {
+ logged = true;
+ ALOGI("hasGSM(gsm.current.phone-type='%s'): %s", ph.c_str(), gsm ? "true" : "false");
+ }
+ return gsm;
+}
+
+static bool isTV() {
+ if (hasGSM()) return false; // TVs don't do GSM
+
+ static string key = base::GetProperty("ro.oem.key1", "");
+ static bool tv = StartsWith(key, "ATV00");
+ static bool logged = false;
+ if (!logged) {
+ logged = true;
+ ALOGI("isTV(ro.oem.key1='%s'): %s.", key.c_str(), tv ? "true" : "false");
+ }
+ return tv;
+}
+
static int doLoad(char** argv, char * const envp[]) {
const int device_api_level = android_get_device_api_level();
const bool isAtLeastT = (device_api_level >= __ANDROID_API_T__);
@@ -278,7 +303,7 @@
if (isAtLeastV && isX86() && !isKernel64Bit()) {
ALOGE("Android V requires X86 kernel to be 64-bit.");
- return 1;
+ if (!isTV()) return 1;
}
if (isAtLeastV) {
@@ -330,7 +355,7 @@
* and 32-bit userspace on 64-bit kernel bpf ringbuffer compatibility is broken.
*/
ALOGE("64-bit userspace required on 6.2+ kernels.");
- return 1;
+ if (!isTV()) return 1;
}
// Ensure we can determine the Android build type.
diff --git a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
index 385adc6..a92dfaf 100644
--- a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
+++ b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
@@ -193,7 +193,8 @@
* @param sentQueryCount The count of sent queries before stop discovery.
*/
public void reportServiceDiscoveryStop(boolean isLegacy, int transactionId, long durationMs,
- int foundCallbackCount, int lostCallbackCount, int servicesCount, int sentQueryCount) {
+ int foundCallbackCount, int lostCallbackCount, int servicesCount, int sentQueryCount,
+ boolean isServiceFromCache) {
final Builder builder = makeReportedBuilder(isLegacy, transactionId);
builder.setType(NsdEventType.NET_DISCOVER);
builder.setQueryResult(MdnsQueryResult.MQR_SERVICE_DISCOVERY_STOP);
@@ -202,6 +203,7 @@
builder.setLostCallbackCount(lostCallbackCount);
builder.setFoundServiceCount(servicesCount);
builder.setSentQueryCount(sentQueryCount);
+ builder.setIsKnownService(isServiceFromCache);
mDependencies.statsWrite(builder.build());
}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 0a8adf0..f8b0d53 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -1634,6 +1634,12 @@
NsdManager.nameOf(code), transactionId));
switch (code) {
case NsdManager.SERVICE_FOUND:
+ // Set the ServiceFromCache flag only if the service is actually being
+ // retrieved from the cache. This flag should not be overridden by later
+ // service found event, which may not be cached.
+ if (event.mIsServiceFromCache) {
+ request.setServiceFromCache(true);
+ }
clientInfo.onServiceFound(clientRequestId, info, request);
break;
case NsdManager.SERVICE_LOST:
@@ -2887,7 +2893,8 @@
request.getFoundServiceCount(),
request.getLostServiceCount(),
request.getServicesCount(),
- request.getSentQueryCount());
+ request.getSentQueryCount(),
+ request.isServiceFromCache());
} else if (listener instanceof ResolutionListener) {
mMetrics.reportServiceResolutionStop(false /* isLegacy */, transactionId,
request.calculateRequestDurationMs(mClock.elapsedRealtime()),
@@ -2927,7 +2934,8 @@
request.getFoundServiceCount(),
request.getLostServiceCount(),
request.getServicesCount(),
- NO_SENT_QUERY_COUNT);
+ NO_SENT_QUERY_COUNT,
+ request.isServiceFromCache());
break;
case NsdManager.RESOLVE_SERVICE:
stopResolveService(transactionId);
@@ -3050,7 +3058,8 @@
request.getFoundServiceCount(),
request.getLostServiceCount(),
request.getServicesCount(),
- request.getSentQueryCount());
+ request.getSentQueryCount(),
+ request.isServiceFromCache());
try {
mCb.onStopDiscoverySucceeded(listenerKey);
} catch (RemoteException e) {
diff --git a/tests/cts/net/src/android/net/cts/ApfIntegrationTest.kt b/tests/cts/net/src/android/net/cts/ApfIntegrationTest.kt
index cd7ea94..90fb7a9 100644
--- a/tests/cts/net/src/android/net/cts/ApfIntegrationTest.kt
+++ b/tests/cts/net/src/android/net/cts/ApfIntegrationTest.kt
@@ -192,8 +192,8 @@
futureReply!!.complete(recvbuf.sliceArray(8..<length))
}
- fun sendPing(data: ByteArray) {
- require(data.size == 56)
+ fun sendPing(data: ByteArray, payloadSize: Int) {
+ require(data.size == payloadSize)
// rfc4443#section-4.1: Echo Request Message
// 0 1 2 3
@@ -415,8 +415,13 @@
readProgram() // wait for install completion
// Assert that initial ping does not get filtered.
- val data = ByteArray(56).also { Random.nextBytes(it) }
- packetReader.sendPing(data)
+ val payloadSize = if (getFirstApiLevel() >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ 68
+ } else {
+ 4
+ }
+ val data = ByteArray(payloadSize).also { Random.nextBytes(it) }
+ packetReader.sendPing(data, payloadSize)
assertThat(packetReader.expectPingReply()).isEqualTo(data)
// Generate an APF program that drops the next ping
@@ -436,7 +441,7 @@
installProgram(program)
readProgram() // wait for install completion
- packetReader.sendPing(data)
+ packetReader.sendPing(data, payloadSize)
packetReader.expectPingDropped()
}
@@ -478,8 +483,13 @@
readProgram() // wait for install completion
// Trigger the program by sending a ping and waiting on the reply.
- val data = ByteArray(56).also { Random.nextBytes(it) }
- packetReader.sendPing(data)
+ val payloadSize = if (getFirstApiLevel() >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ 68
+ } else {
+ 4
+ }
+ val data = ByteArray(payloadSize).also { Random.nextBytes(it) }
+ packetReader.sendPing(data, payloadSize)
packetReader.expectPingReply()
val readResult = readProgram()
@@ -487,8 +497,8 @@
expect.withMessage("PROGRAM_SIZE").that(buffer.getInt()).isEqualTo(program.size)
expect.withMessage("RAM_LEN").that(buffer.getInt()).isEqualTo(caps.maximumApfProgramSize)
expect.withMessage("IPV4_HEADER_SIZE").that(buffer.getInt()).isEqualTo(0)
- // Ping packet (64) + IPv6 header (40) + ethernet header (14)
- expect.withMessage("PACKET_SIZE").that(buffer.getInt()).isEqualTo(64 + 40 + 14)
+ // Ping packet payload + ICMPv6 header (8) + IPv6 header (40) + ethernet header (14)
+ expect.withMessage("PACKET_SIZE").that(buffer.getInt()).isEqualTo(payloadSize + 8 + 40 + 14)
expect.withMessage("FILTER_AGE_SECONDS").that(buffer.getInt()).isLessThan(5)
}
@@ -496,6 +506,10 @@
@IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Test
fun testFilterAgeIncreasesBetweenPackets() {
+ // VSR-14 mandates APF to be turned on when the screen is off and the Wi-Fi link
+ // is idle or traffic is less than 10 Mbps. Before that, we don't mandate when the APF
+ // should be turned on.
+ assume().that(getVsrApiLevel()).isAtLeast(34)
assumeApfVersionSupportAtLeast(4)
clearApfMemory()
val gen = ApfV4Generator(4)
@@ -512,8 +526,9 @@
installProgram(gen.generate())
readProgram() // wait for install completion
- val data = ByteArray(56).also { Random.nextBytes(it) }
- packetReader.sendPing(data)
+ val payloadSize = 56
+ val data = ByteArray(payloadSize).also { Random.nextBytes(it) }
+ packetReader.sendPing(data, payloadSize)
packetReader.expectPingReply()
var buffer = ByteBuffer.wrap(readProgram(), counterRegion, 4 /* length */)
@@ -521,7 +536,7 @@
Thread.sleep(5100)
- packetReader.sendPing(data)
+ packetReader.sendPing(data, payloadSize)
packetReader.expectPingReply()
buffer = ByteBuffer.wrap(readProgram(), counterRegion, 4 /* length */)
diff --git a/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt
index aa28e5a..10ba6a4 100644
--- a/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt
+++ b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt
@@ -163,7 +163,8 @@
val sentQueryCount = 150
val metrics = NetworkNsdReportedMetrics(clientId, deps)
metrics.reportServiceDiscoveryStop(true /* isLegacy */, transactionId, durationMs,
- foundCallbackCount, lostCallbackCount, servicesCount, sentQueryCount)
+ foundCallbackCount, lostCallbackCount, servicesCount, sentQueryCount,
+ true /* isServiceFromCache */)
val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java)
verify(deps).statsWrite(eventCaptor.capture())
@@ -179,6 +180,7 @@
assertEquals(servicesCount, it.foundServiceCount)
assertEquals(durationMs, it.eventDurationMillisec)
assertEquals(sentQueryCount, it.sentQueryCount)
+ assertTrue(it.isKnownService)
}
}
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index aece3f7..979e0a1 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -1196,7 +1196,7 @@
Instant.MAX /* expirationTime */);
// Verify onServiceNameDiscovered callback
- listener.onServiceNameDiscovered(foundInfo, false /* isServiceFromCache */);
+ listener.onServiceNameDiscovered(foundInfo, true /* isServiceFromCache */);
verify(discListener, timeout(TIMEOUT_MS)).onServiceFound(argThat(info ->
info.getServiceName().equals(SERVICE_NAME)
// Service type in discovery callbacks has a dot at the end
@@ -1232,7 +1232,7 @@
verify(mSocketProvider, timeout(CLEANUP_DELAY_MS + TIMEOUT_MS)).requestStopWhenInactive();
verify(mMetrics).reportServiceDiscoveryStop(false /* isLegacy */, discId,
10L /* durationMs */, 1 /* foundCallbackCount */, 1 /* lostCallbackCount */,
- 1 /* servicesCount */, 3 /* sentQueryCount */);
+ 1 /* servicesCount */, 3 /* sentQueryCount */, true /* isServiceFromCache */);
}
@Test
diff --git a/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java b/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java
index 0e76930..996d22d 100644
--- a/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java
@@ -30,6 +30,8 @@
import android.net.thread.ActiveOperationalDataset.Builder;
import android.net.thread.ActiveOperationalDataset.SecurityPolicy;
import android.net.thread.OperationalDatasetTimestamp;
+import android.net.thread.utils.ThreadFeatureCheckerRule;
+import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
import android.util.SparseArray;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,6 +40,7 @@
import com.google.common.primitives.Bytes;
import com.google.common.testing.EqualsTester;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,6 +49,7 @@
/** CTS tests for {@link ActiveOperationalDataset}. */
@SmallTest
+@RequiresThreadFeature
@RunWith(AndroidJUnit4.class)
public final class ActiveOperationalDatasetTest {
private static final int TYPE_ACTIVE_TIMESTAMP = 14;
@@ -81,6 +85,8 @@
private static final ActiveOperationalDataset DEFAULT_DATASET =
ActiveOperationalDataset.fromThreadTlvs(VALID_DATASET_TLVS);
+ @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
+
private static byte[] removeTlv(byte[] dataset, int type) {
ByteArrayOutputStream os = new ByteArrayOutputStream(dataset.length);
int i = 0;
diff --git a/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java b/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java
index 9be3d56..4d7c7f1 100644
--- a/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java
@@ -21,12 +21,15 @@
import static org.junit.Assert.assertThrows;
import android.net.thread.OperationalDatasetTimestamp;
+import android.net.thread.utils.ThreadFeatureCheckerRule;
+import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.google.common.testing.EqualsTester;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,8 +37,11 @@
/** Tests for {@link OperationalDatasetTimestamp}. */
@SmallTest
+@RequiresThreadFeature
@RunWith(AndroidJUnit4.class)
public final class OperationalDatasetTimestampTest {
+ @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
+
@Test
public void fromInstant_tooLargeInstant_throwsIllegalArgument() {
assertThrows(
diff --git a/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java b/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java
index 0bb18ce..76be054 100644
--- a/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java
@@ -28,6 +28,8 @@
import android.net.thread.ActiveOperationalDataset.SecurityPolicy;
import android.net.thread.OperationalDatasetTimestamp;
import android.net.thread.PendingOperationalDataset;
+import android.net.thread.utils.ThreadFeatureCheckerRule;
+import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
import android.util.SparseArray;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,6 +38,7 @@
import com.google.common.primitives.Bytes;
import com.google.common.testing.EqualsTester;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,8 +47,11 @@
/** Tests for {@link PendingOperationalDataset}. */
@SmallTest
+@RequiresThreadFeature
@RunWith(AndroidJUnit4.class)
public final class PendingOperationalDatasetTest {
+ @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
+
private static ActiveOperationalDataset createActiveDataset() throws Exception {
SparseArray<byte[]> channelMask = new SparseArray<>(1);
channelMask.put(0, new byte[] {0x00, 0x1f, (byte) 0xff, (byte) 0xe0});
diff --git a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkExceptionTest.java b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkExceptionTest.java
index 7d9ae81..4de2e13 100644
--- a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkExceptionTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkExceptionTest.java
@@ -25,17 +25,23 @@
import static org.junit.Assert.assertThrows;
import android.net.thread.ThreadNetworkException;
+import android.net.thread.utils.ThreadFeatureCheckerRule;
+import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** CTS tests for {@link ThreadNetworkException}. */
@SmallTest
+@RequiresThreadFeature
@RunWith(AndroidJUnit4.class)
public final class ThreadNetworkExceptionTest {
+ @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
+
@Test
public void constructor_validValues_valuesAreConnectlySet() throws Exception {
ThreadNetworkException errorThreadDisabled =
diff --git a/thread/tests/utils/src/android/net/thread/utils/ThreadFeatureCheckerRule.java b/thread/tests/utils/src/android/net/thread/utils/ThreadFeatureCheckerRule.java
index bee9ceb..38a6e90 100644
--- a/thread/tests/utils/src/android/net/thread/utils/ThreadFeatureCheckerRule.java
+++ b/thread/tests/utils/src/android/net/thread/utils/ThreadFeatureCheckerRule.java
@@ -21,7 +21,6 @@
import static org.junit.Assume.assumeTrue;
import android.content.Context;
-import android.net.thread.ThreadNetworkManager;
import android.os.SystemProperties;
import android.os.VintfRuntimeInfo;
@@ -122,7 +121,10 @@
/** Returns {@code true} if this device has the Thread feature supported. */
private static boolean hasThreadFeature() {
final Context context = ApplicationProvider.getApplicationContext();
- return context.getSystemService(ThreadNetworkManager.class) != null;
+
+ // Use service name rather than `ThreadNetworkManager.class` to avoid
+ // `ClassNotFoundException` on U- devices.
+ return context.getSystemService("thread_network") != null;
}
/**