Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +103 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; Loading @@ -28,6 +31,7 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; Loading Loading @@ -145,6 +149,7 @@ import android.net.MatchAllNetworkSpecifier; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; Loading Loading @@ -244,6 +249,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import kotlin.reflect.KClass; Loading Loading @@ -330,6 +336,9 @@ public class ConnectivityServiceTest { private class MockContext extends BroadcastInterceptingContext { private final MockContentResolver mContentResolver; // Contains all registered receivers since this object was created. Useful to clear // them when needed, as BroadcastInterceptingContext does not provide this facility. private final List<BroadcastReceiver> mRegisteredReceivers = new ArrayList<>(); @Spy private Resources mResources; private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); Loading @@ -343,6 +352,7 @@ public class ConnectivityServiceTest { "wifi,1,1,1,-1,true", "mobile,0,0,0,-1,true", "mobile_mms,2,0,2,60000,true", "mobile_supl,3,0,2,60000,true", }); when(mResources.getStringArray( Loading Loading @@ -410,6 +420,19 @@ public class ConnectivityServiceTest { // make sure the code does not rely on unexpected permissions. super.enforceCallingOrSelfPermission(permission, message); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { mRegisteredReceivers.add(receiver); return super.registerReceiver(receiver, filter); } public void clearRegisteredReceivers() { // super.unregisterReceiver is a no-op for receivers that are not registered (because // they haven't been registered or because they have already been unregistered). // For the same reason, don't bother clearing mRegisteredReceivers. for (final BroadcastReceiver rcv : mRegisteredReceivers) unregisterReceiver(rcv); } } private void waitForIdle() { Loading Loading @@ -1228,16 +1251,25 @@ public class ConnectivityServiceTest { * broadcasts are received. */ private ConditionVariable waitForConnectivityBroadcasts(final int count) { return waitForConnectivityBroadcasts(count, intent -> true); } private ConditionVariable waitForConnectivityBroadcasts(final int count, @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); mServiceContext.registerReceiver(new BroadcastReceiver() { final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { if (!filter.test(intent)) return; if (--remaining == 0) { cv.open(); mServiceContext.unregisterReceiver(this); } } }, new IntentFilter(CONNECTIVITY_ACTION)); }; mServiceContext.registerReceiver(receiver, intentFilter); return cv; } Loading @@ -1257,6 +1289,75 @@ public class ConnectivityServiceTest { assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); } @Test public void testNetworkFeature() throws Exception { // Connect the cell agent and wait for the connected broadcast. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); final ConditionVariable cv1 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE); mCellNetworkAgent.connect(true); waitFor(cv1); // Build legacy request for SUPL. final NetworkCapabilities legacyCaps = new NetworkCapabilities(); legacyCaps.addTransportType(TRANSPORT_CELLULAR); legacyCaps.addCapability(NET_CAPABILITY_SUPL); final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); // Send request and check that the legacy broadcast for SUPL is sent correctly. final TestNetworkCallback callback = new TestNetworkCallback(); final ConditionVariable cv2 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.requestNetwork(legacyRequest, callback); callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv2); // File another request, withdraw it and make sure no broadcast is sent final ConditionVariable cv3 = waitForConnectivityBroadcasts(1); final TestNetworkCallback callback2 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback2); callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); mCm.unregisterNetworkCallback(callback2); assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent // As the broadcast did not fire, the receiver was not unregistered. Do this now. mServiceContext.clearRegisteredReceivers(); // Withdraw the request and check that the broadcast for disconnection is sent. final ConditionVariable cv4 = waitForConnectivityBroadcasts(1, intent -> !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.unregisterNetworkCallback(callback); waitFor(cv4); // Re-file the request and expect the connected broadcast again final ConditionVariable cv5 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); final TestNetworkCallback callback3 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback3); callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv5); // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one // for mobile. Use a small hack to check that both have been sent, but the order is // not contractual. final AtomicBoolean vanillaAction = new AtomicBoolean(false); final AtomicBoolean suplAction = new AtomicBoolean(false); final ConditionVariable cv6 = waitForConnectivityBroadcasts(2, intent -> { if (intent.getAction().equals(CONNECTIVITY_ACTION)) { vanillaAction.set(true); } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { suplAction.set(true); } return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); }); mCellNetworkAgent.disconnect(); waitFor(cv6); assertTrue(vanillaAction.get()); assertTrue(suplAction.get()); } @Test public void testLingering() throws Exception { verifyNoNetwork(); Loading tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +22 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server import android.net.ConnectivityManager.TYPE_ETHERNET import android.net.ConnectivityManager.TYPE_MOBILE import android.net.ConnectivityManager.TYPE_MOBILE_SUPL import android.net.ConnectivityManager.TYPE_WIFI import android.net.ConnectivityManager.TYPE_WIMAX import android.net.NetworkInfo.DetailedState.CONNECTED Loading Loading @@ -46,7 +47,7 @@ const val UNSUPPORTED_TYPE = TYPE_WIMAX @RunWith(AndroidJUnit4::class) @SmallTest class LegacyTypeTrackerTest { private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET) private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_SUPL) private val mMockService = mock(ConnectivityService::class.java).apply { doReturn(false).`when`(this).isDefaultNetwork(any()) Loading @@ -69,6 +70,26 @@ class LegacyTypeTrackerTest { assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE)) } @Test fun testSupl() { val mobileNai = mock(NetworkAgentInfo::class.java) mTracker.add(TYPE_MOBILE, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE) reset(mMockService) mTracker.add(TYPE_MOBILE_SUPL, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.remove(TYPE_MOBILE_SUPL, mobileNai, false /* wasDefault */) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.add(TYPE_MOBILE_SUPL, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.remove(mobileNai, false) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE) } @Test fun testAddNetwork() { val mobileNai = mock(NetworkAgentInfo::class.java) Loading Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +103 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; Loading @@ -28,6 +31,7 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; Loading Loading @@ -145,6 +149,7 @@ import android.net.MatchAllNetworkSpecifier; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; Loading Loading @@ -244,6 +249,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import kotlin.reflect.KClass; Loading Loading @@ -330,6 +336,9 @@ public class ConnectivityServiceTest { private class MockContext extends BroadcastInterceptingContext { private final MockContentResolver mContentResolver; // Contains all registered receivers since this object was created. Useful to clear // them when needed, as BroadcastInterceptingContext does not provide this facility. private final List<BroadcastReceiver> mRegisteredReceivers = new ArrayList<>(); @Spy private Resources mResources; private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); Loading @@ -343,6 +352,7 @@ public class ConnectivityServiceTest { "wifi,1,1,1,-1,true", "mobile,0,0,0,-1,true", "mobile_mms,2,0,2,60000,true", "mobile_supl,3,0,2,60000,true", }); when(mResources.getStringArray( Loading Loading @@ -410,6 +420,19 @@ public class ConnectivityServiceTest { // make sure the code does not rely on unexpected permissions. super.enforceCallingOrSelfPermission(permission, message); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { mRegisteredReceivers.add(receiver); return super.registerReceiver(receiver, filter); } public void clearRegisteredReceivers() { // super.unregisterReceiver is a no-op for receivers that are not registered (because // they haven't been registered or because they have already been unregistered). // For the same reason, don't bother clearing mRegisteredReceivers. for (final BroadcastReceiver rcv : mRegisteredReceivers) unregisterReceiver(rcv); } } private void waitForIdle() { Loading Loading @@ -1228,16 +1251,25 @@ public class ConnectivityServiceTest { * broadcasts are received. */ private ConditionVariable waitForConnectivityBroadcasts(final int count) { return waitForConnectivityBroadcasts(count, intent -> true); } private ConditionVariable waitForConnectivityBroadcasts(final int count, @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); mServiceContext.registerReceiver(new BroadcastReceiver() { final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { if (!filter.test(intent)) return; if (--remaining == 0) { cv.open(); mServiceContext.unregisterReceiver(this); } } }, new IntentFilter(CONNECTIVITY_ACTION)); }; mServiceContext.registerReceiver(receiver, intentFilter); return cv; } Loading @@ -1257,6 +1289,75 @@ public class ConnectivityServiceTest { assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); } @Test public void testNetworkFeature() throws Exception { // Connect the cell agent and wait for the connected broadcast. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); final ConditionVariable cv1 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE); mCellNetworkAgent.connect(true); waitFor(cv1); // Build legacy request for SUPL. final NetworkCapabilities legacyCaps = new NetworkCapabilities(); legacyCaps.addTransportType(TRANSPORT_CELLULAR); legacyCaps.addCapability(NET_CAPABILITY_SUPL); final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); // Send request and check that the legacy broadcast for SUPL is sent correctly. final TestNetworkCallback callback = new TestNetworkCallback(); final ConditionVariable cv2 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.requestNetwork(legacyRequest, callback); callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv2); // File another request, withdraw it and make sure no broadcast is sent final ConditionVariable cv3 = waitForConnectivityBroadcasts(1); final TestNetworkCallback callback2 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback2); callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); mCm.unregisterNetworkCallback(callback2); assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent // As the broadcast did not fire, the receiver was not unregistered. Do this now. mServiceContext.clearRegisteredReceivers(); // Withdraw the request and check that the broadcast for disconnection is sent. final ConditionVariable cv4 = waitForConnectivityBroadcasts(1, intent -> !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.unregisterNetworkCallback(callback); waitFor(cv4); // Re-file the request and expect the connected broadcast again final ConditionVariable cv5 = waitForConnectivityBroadcasts(1, intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); final TestNetworkCallback callback3 = new TestNetworkCallback(); mCm.requestNetwork(legacyRequest, callback3); callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); waitFor(cv5); // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one // for mobile. Use a small hack to check that both have been sent, but the order is // not contractual. final AtomicBoolean vanillaAction = new AtomicBoolean(false); final AtomicBoolean suplAction = new AtomicBoolean(false); final ConditionVariable cv6 = waitForConnectivityBroadcasts(2, intent -> { if (intent.getAction().equals(CONNECTIVITY_ACTION)) { vanillaAction.set(true); } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { suplAction.set(true); } return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); }); mCellNetworkAgent.disconnect(); waitFor(cv6); assertTrue(vanillaAction.get()); assertTrue(suplAction.get()); } @Test public void testLingering() throws Exception { verifyNoNetwork(); Loading
tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +22 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server import android.net.ConnectivityManager.TYPE_ETHERNET import android.net.ConnectivityManager.TYPE_MOBILE import android.net.ConnectivityManager.TYPE_MOBILE_SUPL import android.net.ConnectivityManager.TYPE_WIFI import android.net.ConnectivityManager.TYPE_WIMAX import android.net.NetworkInfo.DetailedState.CONNECTED Loading Loading @@ -46,7 +47,7 @@ const val UNSUPPORTED_TYPE = TYPE_WIMAX @RunWith(AndroidJUnit4::class) @SmallTest class LegacyTypeTrackerTest { private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET) private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_SUPL) private val mMockService = mock(ConnectivityService::class.java).apply { doReturn(false).`when`(this).isDefaultNetwork(any()) Loading @@ -69,6 +70,26 @@ class LegacyTypeTrackerTest { assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE)) } @Test fun testSupl() { val mobileNai = mock(NetworkAgentInfo::class.java) mTracker.add(TYPE_MOBILE, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE) reset(mMockService) mTracker.add(TYPE_MOBILE_SUPL, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.remove(TYPE_MOBILE_SUPL, mobileNai, false /* wasDefault */) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.add(TYPE_MOBILE_SUPL, mobileNai) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) reset(mMockService) mTracker.remove(mobileNai, false) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE) } @Test fun testAddNetwork() { val mobileNai = mock(NetworkAgentInfo::class.java) Loading