Merge "Add tests for the legacy broadcast"
This commit is contained in:
@@ -20,6 +20,9 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
|||||||
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
||||||
import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
|
import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
|
||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
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.NETID_UNSET;
|
||||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
|
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
|
||||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||||
@@ -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;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
|
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.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
|
||||||
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
|
||||||
@@ -145,6 +149,7 @@ import android.net.MatchAllNetworkSpecifier;
|
|||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkFactory;
|
import android.net.NetworkFactory;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkSpecifier;
|
import android.net.NetworkSpecifier;
|
||||||
import android.net.NetworkStack;
|
import android.net.NetworkStack;
|
||||||
@@ -244,6 +249,7 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import kotlin.reflect.KClass;
|
import kotlin.reflect.KClass;
|
||||||
|
|
||||||
@@ -330,6 +336,9 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
private class MockContext extends BroadcastInterceptingContext {
|
private class MockContext extends BroadcastInterceptingContext {
|
||||||
private final MockContentResolver mContentResolver;
|
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;
|
@Spy private Resources mResources;
|
||||||
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
|
||||||
@@ -343,6 +352,7 @@ public class ConnectivityServiceTest {
|
|||||||
"wifi,1,1,1,-1,true",
|
"wifi,1,1,1,-1,true",
|
||||||
"mobile,0,0,0,-1,true",
|
"mobile,0,0,0,-1,true",
|
||||||
"mobile_mms,2,0,2,60000,true",
|
"mobile_mms,2,0,2,60000,true",
|
||||||
|
"mobile_supl,3,0,2,60000,true",
|
||||||
});
|
});
|
||||||
|
|
||||||
when(mResources.getStringArray(
|
when(mResources.getStringArray(
|
||||||
@@ -410,6 +420,19 @@ public class ConnectivityServiceTest {
|
|||||||
// make sure the code does not rely on unexpected permissions.
|
// make sure the code does not rely on unexpected permissions.
|
||||||
super.enforceCallingOrSelfPermission(permission, message);
|
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() {
|
private void waitForIdle() {
|
||||||
@@ -1228,16 +1251,25 @@ public class ConnectivityServiceTest {
|
|||||||
* broadcasts are received.
|
* broadcasts are received.
|
||||||
*/
|
*/
|
||||||
private ConditionVariable waitForConnectivityBroadcasts(final int count) {
|
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();
|
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;
|
private int remaining = count;
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (!filter.test(intent)) return;
|
||||||
if (--remaining == 0) {
|
if (--remaining == 0) {
|
||||||
cv.open();
|
cv.open();
|
||||||
mServiceContext.unregisterReceiver(this);
|
mServiceContext.unregisterReceiver(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, new IntentFilter(CONNECTIVITY_ACTION));
|
};
|
||||||
|
mServiceContext.registerReceiver(receiver, intentFilter);
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,6 +1289,75 @@ public class ConnectivityServiceTest {
|
|||||||
assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET));
|
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
|
@Test
|
||||||
public void testLingering() throws Exception {
|
public void testLingering() throws Exception {
|
||||||
verifyNoNetwork();
|
verifyNoNetwork();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server
|
|||||||
|
|
||||||
import android.net.ConnectivityManager.TYPE_ETHERNET
|
import android.net.ConnectivityManager.TYPE_ETHERNET
|
||||||
import android.net.ConnectivityManager.TYPE_MOBILE
|
import android.net.ConnectivityManager.TYPE_MOBILE
|
||||||
|
import android.net.ConnectivityManager.TYPE_MOBILE_SUPL
|
||||||
import android.net.ConnectivityManager.TYPE_WIFI
|
import android.net.ConnectivityManager.TYPE_WIFI
|
||||||
import android.net.ConnectivityManager.TYPE_WIMAX
|
import android.net.ConnectivityManager.TYPE_WIMAX
|
||||||
import android.net.NetworkInfo.DetailedState.CONNECTED
|
import android.net.NetworkInfo.DetailedState.CONNECTED
|
||||||
@@ -46,7 +47,7 @@ const val UNSUPPORTED_TYPE = TYPE_WIMAX
|
|||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
class LegacyTypeTrackerTest {
|
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 {
|
private val mMockService = mock(ConnectivityService::class.java).apply {
|
||||||
doReturn(false).`when`(this).isDefaultNetwork(any())
|
doReturn(false).`when`(this).isDefaultNetwork(any())
|
||||||
@@ -69,6 +70,26 @@ class LegacyTypeTrackerTest {
|
|||||||
assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE))
|
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
|
@Test
|
||||||
fun testAddNetwork() {
|
fun testAddNetwork() {
|
||||||
val mobileNai = mock(NetworkAgentInfo::class.java)
|
val mobileNai = mock(NetworkAgentInfo::class.java)
|
||||||
|
|||||||
Reference in New Issue
Block a user