Snap for 7478986 from 858dde41094147811515a77c8adafe274607ad08 to sc-release
Change-Id: Ia974ce48c88f385b6422e82343f8ca09e544c40a
diff --git a/tests/common/java/android/net/NetworkProviderTest.kt b/tests/common/java/android/net/NetworkProviderTest.kt
index 97d3c5a..8cea12e 100644
--- a/tests/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/common/java/android/net/NetworkProviderTest.kt
@@ -18,12 +18,14 @@
import android.app.Instrumentation
import android.content.Context
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
import android.net.NetworkCapabilities.TRANSPORT_TEST
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
import android.os.Build
+import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log
@@ -34,6 +36,7 @@
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.TestableNetworkOfferCallback
import com.android.testutils.isDevSdkInRange
import org.junit.After
import org.junit.Before
@@ -44,11 +47,14 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.verifyNoMoreInteractions
import java.util.UUID
+import java.util.concurrent.Executor
+import java.util.concurrent.RejectedExecutionException
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.fail
private const val DEFAULT_TIMEOUT_MS = 5000L
+private const val DEFAULT_NO_CALLBACK_TIMEOUT_MS = 200L
private val instrumentation: Instrumentation
get() = InstrumentationRegistry.getInstrumentation()
private val context: Context get() = InstrumentationRegistry.getContext()
@@ -102,12 +108,24 @@
crossinline predicate: (T) -> Boolean
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
?: fail("Did not receive callback after ${DEFAULT_TIMEOUT_MS}ms")
+
+ fun assertNoCallback() {
+ val cb = seenEvents.poll(DEFAULT_NO_CALLBACK_TIMEOUT_MS)
+ if (null != cb) fail("Expected no callback but got $cb")
+ }
}
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
return TestNetworkProvider(ctx, mHandlerThread.looper)
}
+ private fun createAndRegisterNetworkProvider(ctx: Context = context) =
+ createNetworkProvider(ctx).also {
+ assertEquals(it.getProviderId(), NetworkProvider.ID_NONE)
+ mCm.registerNetworkProvider(it)
+ assertNotEquals(it.getProviderId(), NetworkProvider.ID_NONE)
+ }
+
// In S+ framework, do not run this test, since the provider will no longer receive
// onNetworkRequested for every request. Instead, provider needs to
// call {@code registerNetworkOffer} with the description of networks they
@@ -115,10 +133,7 @@
@IgnoreAfter(Build.VERSION_CODES.R)
@Test
fun testOnNetworkRequested() {
- val provider = createNetworkProvider()
- assertEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
- mCm.registerNetworkProvider(provider)
- assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
+ val provider = createAndRegisterNetworkProvider()
val specifier = CompatUtil.makeTestNetworkSpecifier(
UUID.randomUUID().toString())
@@ -179,6 +194,167 @@
mCm.unregisterNetworkProvider(provider)
}
+ // Mainline module can't use internal HandlerExecutor, so add an identical executor here.
+ // TODO: Refactor with the one in MultiNetworkPolicyTracker.
+ private class HandlerExecutor(private val handler: Handler) : Executor {
+ public override fun execute(command: Runnable) {
+ if (!handler.post(command)) {
+ throw RejectedExecutionException(handler.toString() + " is shutting down")
+ }
+ }
+ }
+
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ @Test
+ fun testRegisterNetworkOffer() {
+ val provider = createAndRegisterNetworkProvider()
+ val provider2 = createAndRegisterNetworkProvider()
+
+ // Prepare the materials which will be used to create different offers.
+ val specifier1 = CompatUtil.makeTestNetworkSpecifier("TEST-SPECIFIER-1")
+ val specifier2 = CompatUtil.makeTestNetworkSpecifier("TEST-SPECIFIER-2")
+ val scoreWeaker = NetworkScore.Builder().build()
+ val scoreStronger = NetworkScore.Builder().setTransportPrimary(true).build()
+ val ncFilter1 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
+ .setNetworkSpecifier(specifier1).build()
+ val ncFilter2 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .setNetworkSpecifier(specifier1).build()
+ val ncFilter3 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
+ .setNetworkSpecifier(specifier2).build()
+ val ncFilter4 = NetworkCapabilities.Builder().addTransportType(TRANSPORT_TEST)
+ .setNetworkSpecifier(specifier2).build()
+
+ // Make 4 offers, where 1 doesn't have NOT_VCN, 2 has NOT_VCN, 3 is similar to 1 but with
+ // different specifier, and 4 is also similar to 1 but with different provider.
+ val offerCallback1 = TestableNetworkOfferCallback(
+ DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
+ val offerCallback2 = TestableNetworkOfferCallback(
+ DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
+ val offerCallback3 = TestableNetworkOfferCallback(
+ DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
+ val offerCallback4 = TestableNetworkOfferCallback(
+ DEFAULT_TIMEOUT_MS, DEFAULT_NO_CALLBACK_TIMEOUT_MS)
+ provider.registerNetworkOffer(scoreWeaker, ncFilter1,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback1)
+ provider.registerNetworkOffer(scoreStronger, ncFilter2,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback2)
+ provider.registerNetworkOffer(scoreWeaker, ncFilter3,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback3)
+ provider2.registerNetworkOffer(scoreWeaker, ncFilter4,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback4)
+ // Unlike Android R, Android S+ provider will only receive interested requests via offer
+ // callback. Verify that the callbacks do not see any existing request such as default
+ // requests.
+ offerCallback1.assertNoCallback()
+ offerCallback2.assertNoCallback()
+ offerCallback3.assertNoCallback()
+ offerCallback4.assertNoCallback()
+
+ // File a request with specifier but without NOT_VCN, verify network is needed for callback
+ // with the same specifier.
+ val nrNoNotVcn: NetworkRequest = NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_TEST)
+ // Test network is not allowed to be trusted.
+ .removeCapability(NET_CAPABILITY_TRUSTED)
+ .setNetworkSpecifier(specifier1)
+ .build()
+ val cb1 = ConnectivityManager.NetworkCallback()
+ mCm.requestNetwork(nrNoNotVcn, cb1)
+ offerCallback1.expectOnNetworkNeeded(ncFilter1)
+ offerCallback2.expectOnNetworkNeeded(ncFilter2)
+ offerCallback3.assertNoCallback()
+ offerCallback4.assertNoCallback()
+
+ mCm.unregisterNetworkCallback(cb1)
+ offerCallback1.expectOnNetworkUnneeded(ncFilter1)
+ offerCallback2.expectOnNetworkUnneeded(ncFilter2)
+ offerCallback3.assertNoCallback()
+ offerCallback4.assertNoCallback()
+
+ // File a request without specifier but with NOT_VCN, verify network is needed for offer
+ // with NOT_VCN.
+ val nrNotVcn: NetworkRequest = NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_TEST)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ // Test network is not allowed to be trusted.
+ .removeCapability(NET_CAPABILITY_TRUSTED)
+ .build()
+ val cb2 = ConnectivityManager.NetworkCallback()
+ mCm.requestNetwork(nrNotVcn, cb2)
+ offerCallback1.assertNoCallback()
+ offerCallback2.expectOnNetworkNeeded(ncFilter2)
+ offerCallback3.assertNoCallback()
+ offerCallback4.assertNoCallback()
+
+ // Upgrade offer 3 & 4 to satisfy previous request and then verify they are also needed.
+ ncFilter3.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ provider.registerNetworkOffer(scoreWeaker, ncFilter3,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback3)
+ ncFilter4.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ provider2.registerNetworkOffer(scoreWeaker, ncFilter4,
+ HandlerExecutor(mHandlerThread.threadHandler), offerCallback4)
+ offerCallback1.assertNoCallback()
+ offerCallback2.assertNoCallback()
+ offerCallback3.expectOnNetworkNeeded(ncFilter3)
+ offerCallback4.expectOnNetworkNeeded(ncFilter4)
+
+ // Connect an agent to fulfill the request, verify offer 4 is not needed since it is not
+ // from currently serving provider nor can beat the current satisfier.
+ val nc = NetworkCapabilities().apply {
+ addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+ removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+ addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
+ addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
+ addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ setNetworkSpecifier(specifier1)
+ }
+ val config = NetworkAgentConfig.Builder().build()
+ val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc,
+ LinkProperties(), scoreWeaker, config, provider) {}
+ agent.register()
+ agent.markConnected()
+ // TODO: The request is satisying by offer 2 instead of offer 1, thus it should not be
+ // considered as needed.
+ offerCallback1.expectOnNetworkNeeded(ncFilter2)
+ offerCallback2.assertNoCallback() // Still needed.
+ offerCallback3.assertNoCallback() // Still needed.
+ offerCallback4.expectOnNetworkUnneeded(ncFilter4)
+
+ // Upgrade the agent, verify no change since the framework will treat the offer as needed
+ // if a request is currently satisfied by the network provided by the same provider.
+ // TODO: Consider offers with weaker score are unneeded.
+ agent.sendNetworkScore(scoreStronger)
+ offerCallback1.assertNoCallback()
+ offerCallback2.assertNoCallback() // Still needed.
+ offerCallback3.assertNoCallback() // Still needed.
+ offerCallback4.assertNoCallback() // Still unneeded.
+
+ // Verify that offer callbacks cannot receive any event if offer is unregistered.
+ provider2.unregisterNetworkOffer(offerCallback4)
+ agent.unregister()
+ offerCallback1.assertNoCallback() // Still needed.
+ offerCallback2.assertNoCallback() // Still needed.
+ offerCallback3.assertNoCallback() // Still needed.
+ // Since the agent is unregistered, and the offer has chance to satisfy the request,
+ // this callback should receive needed if it is not unregistered.
+ offerCallback4.assertNoCallback()
+
+ // Verify that offer callbacks cannot receive any event if provider is unregistered.
+ mCm.unregisterNetworkProvider(provider)
+ mCm.unregisterNetworkCallback(cb2)
+ offerCallback1.assertNoCallback() // Should be unneeded if not unregistered.
+ offerCallback2.assertNoCallback() // Should be unneeded if not unregistered.
+ offerCallback3.assertNoCallback() // Should be unneeded if not unregistered.
+ offerCallback4.assertNoCallback() // Already unregistered.
+
+ // Clean up and Verify providers did not receive any callback during the entire test.
+ mCm.unregisterNetworkProvider(provider2)
+ provider.assertNoCallback()
+ provider2.assertNoCallback()
+ }
+
private class TestNetworkCallback : ConnectivityManager.NetworkCallback() {
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
sealed class CallbackEntry {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index f9454ad..5b95eea 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -126,6 +126,8 @@
private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
private static final String KEY_SKIP_VALIDATION_CHECKS = TEST_PKG + ".skip_validation_checks";
+ private static final String EMPTY_STRING = "";
+
protected static final int TYPE_COMPONENT_ACTIVTIY = 0;
protected static final int TYPE_COMPONENT_FOREGROUND_SERVICE = 1;
protected static final int TYPE_EXPEDITED_JOB = 2;
@@ -229,6 +231,8 @@
final String resultData = getResultData();
if (resultData == null) {
Log.e(TAG, "Received null data from ordered intent");
+ // Offer an empty string so that the code waiting for the result can return.
+ result.offer(EMPTY_STRING);
return;
}
result.offer(resultData);
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index ae59dc4..34f3cc9 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -28,6 +28,7 @@
import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
@@ -2104,6 +2105,20 @@
}
}
+ /**
+ * Verify that {@link ConnectivityManager#setProfileNetworkPreference} cannot be called
+ * without required NETWORK_STACK permissions.
+ */
+ @Test
+ public void testSetProfileNetworkPreference_NoPermission() {
+ // Cannot use @IgnoreUpTo(Build.VERSION_CODES.R) because this test also requires API 31
+ // shims, and @IgnoreUpTo does not check that.
+ assumeTrue(TestUtils.shouldTestSApis());
+ assertThrows(SecurityException.class, () -> mCm.setProfileNetworkPreference(
+ UserHandle.of(0), PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null /* executor */,
+ null /* listener */));
+ }
+
private void verifySettings(int expectedAirplaneMode, int expectedPrivateDnsMode,
int expectedAvoidBadWifi) throws Exception {
assertEquals(expectedAirplaneMode, Settings.Global.getInt(