Make TestConnectivityManager send CONNECTIVITY_ACTION.
The tethering code still depends on CONNECTIVITY_ACTION for upstream selection. Make TestConnectivityManager send these broadcasts. Bug: 173068192 Test: atest TetheringTests Change-Id: I6a32e99fafef9d6d2abec438ffc68164ab4c5bdf
This commit is contained in:
@@ -16,19 +16,20 @@
|
|||||||
|
|
||||||
package com.android.networkstack.tethering;
|
package com.android.networkstack.tethering;
|
||||||
|
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.IConnectivityManager;
|
import android.net.IConnectivityManager;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -39,6 +40,10 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* Simulates upstream switching and sending NetworkCallbacks and CONNECTIVITY_ACTION broadcasts.
|
* Simulates upstream switching and sending NetworkCallbacks and CONNECTIVITY_ACTION broadcasts.
|
||||||
*
|
*
|
||||||
|
* Unlike any real networking code, this class is single-threaded and entirely synchronous.
|
||||||
|
* The effects of all method calls (including sending fake broadcasts, sending callbacks, etc.) are
|
||||||
|
* performed immediately on the caller's thread before returning.
|
||||||
|
*
|
||||||
* TODO: this duplicates a fair amount of code from ConnectivityManager and ConnectivityService.
|
* TODO: this duplicates a fair amount of code from ConnectivityManager and ConnectivityService.
|
||||||
* Consider using a ConnectivityService object instead, as used in ConnectivityServiceTest.
|
* Consider using a ConnectivityService object instead, as used in ConnectivityServiceTest.
|
||||||
*
|
*
|
||||||
@@ -63,11 +68,21 @@ public class TestConnectivityManager extends ConnectivityManager {
|
|||||||
public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
|
public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
|
||||||
|
|
||||||
private final NetworkRequest mDefaultRequest;
|
private final NetworkRequest mDefaultRequest;
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
private int mNetworkId = 100;
|
private int mNetworkId = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a TestConnectivityManager.
|
||||||
|
* @param ctx the context to use. Must be a fake or a mock because otherwise the test will
|
||||||
|
* attempt to send real broadcasts and resulting in permission denials.
|
||||||
|
* @param svc an IConnectivityManager. Should be a fake or a mock.
|
||||||
|
* @param defaultRequest the default NetworkRequest that will be used by Tethering.
|
||||||
|
*/
|
||||||
public TestConnectivityManager(Context ctx, IConnectivityManager svc,
|
public TestConnectivityManager(Context ctx, IConnectivityManager svc,
|
||||||
NetworkRequest defaultRequest) {
|
NetworkRequest defaultRequest) {
|
||||||
super(ctx, svc);
|
super(ctx, svc);
|
||||||
|
mContext = ctx;
|
||||||
mDefaultRequest = defaultRequest;
|
mDefaultRequest = defaultRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +124,13 @@ public class TestConnectivityManager extends ConnectivityManager {
|
|||||||
final TestNetworkAgent formerDefault = defaultNetwork;
|
final TestNetworkAgent formerDefault = defaultNetwork;
|
||||||
defaultNetwork = agent;
|
defaultNetwork = agent;
|
||||||
|
|
||||||
|
if (formerDefault != null) {
|
||||||
|
sendConnectivityAction(formerDefault.legacyType, false /* connected */);
|
||||||
|
}
|
||||||
|
if (defaultNetwork != null) {
|
||||||
|
sendConnectivityAction(defaultNetwork.legacyType, true /* connected */);
|
||||||
|
}
|
||||||
|
|
||||||
for (NetworkCallback cb : trackingDefault) {
|
for (NetworkCallback cb : trackingDefault) {
|
||||||
if (defaultNetwork != null) {
|
if (defaultNetwork != null) {
|
||||||
cb.onAvailable(defaultNetwork.networkId);
|
cb.onAvailable(defaultNetwork.networkId);
|
||||||
@@ -194,24 +216,72 @@ public class TestConnectivityManager extends ConnectivityManager {
|
|||||||
assertFalse(requested.containsKey(cb));
|
assertFalse(requested.containsKey(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendConnectivityAction(int type, boolean connected) {
|
||||||
|
NetworkInfo ni = new NetworkInfo(type, 0 /* subtype */, getNetworkTypeName(type),
|
||||||
|
"" /* subtypeName */);
|
||||||
|
NetworkInfo.DetailedState state = connected
|
||||||
|
? NetworkInfo.DetailedState.CONNECTED
|
||||||
|
: NetworkInfo.DetailedState.DISCONNECTED;
|
||||||
|
ni.setDetailedState(state, "" /* reason */, "" /* extraInfo */);
|
||||||
|
Intent intent = new Intent(CONNECTIVITY_ACTION);
|
||||||
|
intent.putExtra(EXTRA_NETWORK_INFO, ni);
|
||||||
|
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestNetworkAgent {
|
public static class TestNetworkAgent {
|
||||||
public final TestConnectivityManager cm;
|
public final TestConnectivityManager cm;
|
||||||
public final Network networkId;
|
public final Network networkId;
|
||||||
public final int transportType;
|
|
||||||
public final NetworkCapabilities networkCapabilities;
|
public final NetworkCapabilities networkCapabilities;
|
||||||
public final LinkProperties linkProperties;
|
public final LinkProperties linkProperties;
|
||||||
|
// TODO: delete when tethering no longer uses CONNECTIVITY_ACTION.
|
||||||
|
public final int legacyType;
|
||||||
|
|
||||||
public TestNetworkAgent(TestConnectivityManager cm, int transportType) {
|
public TestNetworkAgent(TestConnectivityManager cm, NetworkCapabilities nc) {
|
||||||
this.cm = cm;
|
this.cm = cm;
|
||||||
this.networkId = new Network(cm.getNetworkId());
|
this.networkId = new Network(cm.getNetworkId());
|
||||||
this.transportType = transportType;
|
networkCapabilities = copy(nc);
|
||||||
networkCapabilities = new NetworkCapabilities();
|
|
||||||
networkCapabilities.addTransportType(transportType);
|
|
||||||
networkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
|
|
||||||
linkProperties = new LinkProperties();
|
linkProperties = new LinkProperties();
|
||||||
|
legacyType = toLegacyType(nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestNetworkAgent(TestConnectivityManager cm, UpstreamNetworkState state) {
|
||||||
|
this.cm = cm;
|
||||||
|
networkId = state.network;
|
||||||
|
networkCapabilities = state.networkCapabilities;
|
||||||
|
linkProperties = state.linkProperties;
|
||||||
|
this.legacyType = toLegacyType(networkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int toLegacyType(NetworkCapabilities nc) {
|
||||||
|
for (int type = 0; type < ConnectivityManager.TYPE_TEST; type++) {
|
||||||
|
if (matchesLegacyType(nc, type)) return type;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(("Can't determine legacy type for: ") + nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean matchesLegacyType(NetworkCapabilities nc, int legacyType) {
|
||||||
|
final NetworkCapabilities typeNc;
|
||||||
|
try {
|
||||||
|
typeNc = ConnectivityManager.networkCapabilitiesForType(legacyType);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// networkCapabilitiesForType does not support all legacy types.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return typeNc.satisfiedByNetworkCapabilities(nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesLegacyType(int legacyType) {
|
||||||
|
return matchesLegacyType(networkCapabilities, legacyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fakeConnect() {
|
public void fakeConnect() {
|
||||||
|
for (NetworkRequest request : cm.requested.values()) {
|
||||||
|
if (matchesLegacyType(request.legacyType)) {
|
||||||
|
cm.sendConnectivityAction(legacyType, true /* connected */);
|
||||||
|
// In practice, a given network can match only one legacy type.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (NetworkCallback cb : cm.listening.keySet()) {
|
for (NetworkCallback cb : cm.listening.keySet()) {
|
||||||
cb.onAvailable(networkId);
|
cb.onAvailable(networkId);
|
||||||
cb.onCapabilitiesChanged(networkId, copy(networkCapabilities));
|
cb.onCapabilitiesChanged(networkId, copy(networkCapabilities));
|
||||||
@@ -220,6 +290,12 @@ public class TestConnectivityManager extends ConnectivityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fakeDisconnect() {
|
public void fakeDisconnect() {
|
||||||
|
for (NetworkRequest request : cm.requested.values()) {
|
||||||
|
if (matchesLegacyType(request.legacyType)) {
|
||||||
|
cm.sendConnectivityAction(legacyType, false /* connected */);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (NetworkCallback cb : cm.listening.keySet()) {
|
for (NetworkCallback cb : cm.listening.keySet()) {
|
||||||
cb.onLost(networkId);
|
cb.onLost(networkId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,13 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
// any specific TRANSPORT_* is sufficient to identify this request.
|
// any specific TRANSPORT_* is sufficient to identify this request.
|
||||||
private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
|
private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
|
||||||
|
|
||||||
|
private static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities.Builder()
|
||||||
|
.addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_INTERNET).build();
|
||||||
|
private static final NetworkCapabilities DUN_CAPABILITIES = new NetworkCapabilities.Builder()
|
||||||
|
.addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_DUN).build();
|
||||||
|
private static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities.Builder()
|
||||||
|
.addTransportType(TRANSPORT_WIFI).addCapability(NET_CAPABILITY_INTERNET).build();
|
||||||
|
|
||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
@Mock private EntitlementManager mEntitleMgr;
|
@Mock private EntitlementManager mEntitleMgr;
|
||||||
@Mock private IConnectivityManager mCS;
|
@Mock private IConnectivityManager mCS;
|
||||||
@@ -288,7 +295,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
// There are no networks, so there is nothing to select.
|
// There are no networks, so there is nothing to select.
|
||||||
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
|
|
||||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
|
||||||
wifiAgent.fakeConnect();
|
wifiAgent.fakeConnect();
|
||||||
// WiFi is up, we should prefer it.
|
// WiFi is up, we should prefer it.
|
||||||
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
|
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
@@ -296,7 +303,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
// There are no networks, so there is nothing to select.
|
// There are no networks, so there is nothing to select.
|
||||||
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
|
|
||||||
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
|
||||||
cellAgent.fakeConnect();
|
cellAgent.fakeConnect();
|
||||||
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
|
|
||||||
@@ -337,8 +344,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
mUNM.updateMobileRequiresDun(true);
|
mUNM.updateMobileRequiresDun(true);
|
||||||
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
|
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
|
|
||||||
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, DUN_CAPABILITIES);
|
||||||
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
|
|
||||||
dunAgent.fakeConnect();
|
dunAgent.fakeConnect();
|
||||||
|
|
||||||
// WiFi is still preferred.
|
// WiFi is still preferred.
|
||||||
@@ -370,7 +376,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
mUNM.updateMobileRequiresDun(false);
|
mUNM.updateMobileRequiresDun(false);
|
||||||
|
|
||||||
// [0] Mobile connects, DUN not required -> mobile selected.
|
// [0] Mobile connects, DUN not required -> mobile selected.
|
||||||
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
|
||||||
cellAgent.fakeConnect();
|
cellAgent.fakeConnect();
|
||||||
mCM.makeDefaultNetwork(cellAgent);
|
mCM.makeDefaultNetwork(cellAgent);
|
||||||
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
|
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
|
||||||
@@ -381,7 +387,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
|
when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
|
||||||
|
|
||||||
// [2] WiFi connects but not validated/promoted to default -> mobile selected.
|
// [2] WiFi connects but not validated/promoted to default -> mobile selected.
|
||||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
|
||||||
wifiAgent.fakeConnect();
|
wifiAgent.fakeConnect();
|
||||||
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
|
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
|
||||||
|
|
||||||
@@ -401,7 +407,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
// into UNM we should test for this here.
|
// into UNM we should test for this here.
|
||||||
|
|
||||||
// [6] DUN network arrives -> DUN selected
|
// [6] DUN network arrives -> DUN selected
|
||||||
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
|
||||||
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
|
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
|
||||||
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
|
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
|
||||||
dunAgent.fakeConnect();
|
dunAgent.fakeConnect();
|
||||||
@@ -424,7 +430,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
final Set<String> alreadySeen = new HashSet<>();
|
final Set<String> alreadySeen = new HashSet<>();
|
||||||
|
|
||||||
// [1] Pretend Wi-Fi connects.
|
// [1] Pretend Wi-Fi connects.
|
||||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
|
||||||
final LinkProperties wifiLp = wifiAgent.linkProperties;
|
final LinkProperties wifiLp = wifiAgent.linkProperties;
|
||||||
wifiLp.setInterfaceName("wlan0");
|
wifiLp.setInterfaceName("wlan0");
|
||||||
final String[] wifi_addrs = {
|
final String[] wifi_addrs = {
|
||||||
@@ -451,7 +457,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
assertEquals(alreadySeen.size(), local.size());
|
assertEquals(alreadySeen.size(), local.size());
|
||||||
|
|
||||||
// [2] Pretend mobile connects.
|
// [2] Pretend mobile connects.
|
||||||
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
|
||||||
final LinkProperties cellLp = cellAgent.linkProperties;
|
final LinkProperties cellLp = cellAgent.linkProperties;
|
||||||
cellLp.setInterfaceName("rmnet_data0");
|
cellLp.setInterfaceName("rmnet_data0");
|
||||||
final String[] cell_addrs = {
|
final String[] cell_addrs = {
|
||||||
@@ -472,9 +478,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
assertEquals(alreadySeen.size(), local.size());
|
assertEquals(alreadySeen.size(), local.size());
|
||||||
|
|
||||||
// [3] Pretend DUN connects.
|
// [3] Pretend DUN connects.
|
||||||
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, DUN_CAPABILITIES);
|
||||||
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
|
|
||||||
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
|
|
||||||
final LinkProperties dunLp = dunAgent.linkProperties;
|
final LinkProperties dunLp = dunAgent.linkProperties;
|
||||||
dunLp.setInterfaceName("rmnet_data1");
|
dunLp.setInterfaceName("rmnet_data1");
|
||||||
final String[] dun_addrs = {
|
final String[] dun_addrs = {
|
||||||
@@ -524,11 +528,11 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||||
mUNM.startObserveAllNetworks();
|
mUNM.startObserveAllNetworks();
|
||||||
// Setup wifi and make wifi as default network.
|
// Setup wifi and make wifi as default network.
|
||||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
|
||||||
wifiAgent.fakeConnect();
|
wifiAgent.fakeConnect();
|
||||||
mCM.makeDefaultNetwork(wifiAgent);
|
mCM.makeDefaultNetwork(wifiAgent);
|
||||||
// Setup mobile network.
|
// Setup mobile network.
|
||||||
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
|
||||||
cellAgent.fakeConnect();
|
cellAgent.fakeConnect();
|
||||||
|
|
||||||
assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
|
assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
|
||||||
|
|||||||
Reference in New Issue
Block a user