diff --git a/TEST_MAPPING b/TEST_MAPPING index 34646e2068..4d3ecdfaf0 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -57,6 +57,17 @@ } ] }, + { + "name": "CtsNetTestCasesMaxTargetSdk33", + "options": [ + { + "exclude-annotation": "com.android.testutils.SkipPresubmit" + }, + { + "exclude-annotation": "androidx.test.filters.RequiresDevice" + } + ] + }, { "name": "bpf_existence_test" }, @@ -143,6 +154,17 @@ } ] }, + { + "name": "CtsNetTestCasesMaxTargetSdk33[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]", + "options": [ + { + "exclude-annotation": "com.android.testutils.SkipPresubmit" + }, + { + "exclude-annotation": "androidx.test.filters.RequiresDevice" + } + ] + }, // Test with APK modules only, in cases where APEX is not supported, or the other modules // were simply not updated { diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 23cb15c6bc..f9fe5b011e 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -114,34 +114,39 @@ android_test { ], } -android_test { - name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation. +java_defaults { + name: "CtsNetTestCasesMaxTargetSdkDefaults", defaults: [ "CtsNetTestCasesDefaults", "CtsNetTestCasesApiStableDefaults", ], - target_sdk_version: "31", - package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique. - instrumentation_target_package: "android.net.cts.maxtargetsdk31", test_suites: [ "cts", "general-tests", - "mts-networking", + "mts-tethering", ], } +android_test { + name: "CtsNetTestCasesMaxTargetSdk33", // Must match CtsNetTestCasesMaxTargetSdk33 annotation. + defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"], + target_sdk_version: "33", + package_name: "android.net.cts.maxtargetsdk33", + instrumentation_target_package: "android.net.cts.maxtargetsdk33", +} + +android_test { + name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation. + defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"], + target_sdk_version: "31", + package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique. + instrumentation_target_package: "android.net.cts.maxtargetsdk31", +} + android_test { name: "CtsNetTestCasesMaxTargetSdk30", // Must match CtsNetTestCasesMaxTargetSdk30 annotation. - defaults: [ - "CtsNetTestCasesDefaults", - "CtsNetTestCasesApiStableDefaults", - ], + defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"], target_sdk_version: "30", package_name: "android.net.cts.maxtargetsdk30", // CTS package names must be unique. instrumentation_target_package: "android.net.cts.maxtargetsdk30", - test_suites: [ - "cts", - "general-tests", - "mts-networking", - ], } diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt index 093c7f84ac..de5e46f319 100644 --- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt +++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt @@ -20,6 +20,8 @@ import android.app.compat.CompatChanges import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback import android.net.LinkProperties +import android.net.LocalSocket +import android.net.LocalSocketAddress import android.net.Network import android.net.NetworkAgentConfig import android.net.NetworkCapabilities @@ -63,6 +65,8 @@ import android.platform.test.annotations.AppModeFull import android.util.Log import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.compatibility.common.util.PollingCheck +import com.android.compatibility.common.util.PropertyUtil import com.android.net.module.util.ArrayTrackRecord import com.android.net.module.util.TrackRecord import com.android.networkstack.apishim.NsdShimImpl @@ -72,14 +76,17 @@ import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.TestableNetworkAgent import com.android.testutils.TestableNetworkCallback import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk30 +import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk33 import com.android.testutils.runAsShell import com.android.testutils.tryTest import com.android.testutils.waitForIdle import java.io.File +import java.io.IOException import java.net.ServerSocket import java.nio.charset.StandardCharsets import java.util.Random import java.util.concurrent.Executor +import kotlin.math.min import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertNotNull @@ -763,6 +770,69 @@ class NsdManagerTest { } } + private fun checkConnectSocketToMdnsd(shouldFail: Boolean) { + val discoveryRecord = NsdDiscoveryRecord() + val localSocket = LocalSocket() + tryTest { + // Discover any service from NsdManager to enforce NsdService to start the mdnsd. + nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, discoveryRecord) + discoveryRecord.expectCallback() + + // Checks the /dev/socket/mdnsd is created. + val socket = File("/dev/socket/mdnsd") + val doesSocketExist = PollingCheck.waitFor( + TIMEOUT_MS, + { + socket.exists() + }, + { doesSocketExist -> + doesSocketExist + }, + ) + + // If the socket is not created, then no need to check the access. + if (doesSocketExist) { + // Create a LocalSocket and try to connect to mdnsd. + assertFalse("LocalSocket is connected.", localSocket.isConnected) + val address = LocalSocketAddress("mdnsd", LocalSocketAddress.Namespace.RESERVED) + if (shouldFail) { + assertFailsWith("Expect fail but socket connected") { + localSocket.connect(address) + } + } else { + localSocket.connect(address) + assertTrue("LocalSocket is not connected.", localSocket.isConnected) + } + } + } cleanup { + localSocket.close() + nsdManager.stopServiceDiscovery(discoveryRecord) + discoveryRecord.expectCallback() + } + } + + /** + * Starting from Android U, the access to the /dev/socket/mdnsd is blocked by the + * sepolicy(b/265364111). + */ + @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) + @Test + fun testCannotConnectSocketToMdnsd() { + val targetSdkVersion = context.packageManager + .getTargetSdkVersion(context.applicationInfo.packageName) + assumeTrue(targetSdkVersion > Build.VERSION_CODES.TIRAMISU) + val firstApiLevel = min(PropertyUtil.getFirstApiLevel(), PropertyUtil.getVendorApiLevel()) + // The sepolicy is implemented in the vendor image, so the access may not be blocked if + // the vendor image is not update to date. + assumeTrue(firstApiLevel > Build.VERSION_CODES.TIRAMISU) + checkConnectSocketToMdnsd(shouldFail = true) + } + + @Test @CtsNetTestCasesMaxTargetSdk33("mdnsd socket is accessible up to target SDK 33") + fun testCanConnectSocketToMdnsd() { + checkConnectSocketToMdnsd(shouldFail = false) + } + @Test @CtsNetTestCasesMaxTargetSdk30("Socket is started with the service up to target SDK 30") fun testManagerCreatesLegacySocket() { nsdManager // Ensure the lazy-init member is initialized, so NsdManager is created