Merge "make UpsreamNetworkMonitor the sole source of upstream network information"

This commit is contained in:
Erik Kline
2017-06-13 08:20:40 +00:00
committed by Gerrit Code Review
3 changed files with 45 additions and 46 deletions

View File

@@ -1249,9 +1249,9 @@ public class Tethering extends BaseNetworkObserver {
protected void chooseUpstreamType(boolean tryCell) {
updateConfiguration(); // TODO - remove?
final int upstreamType = mUpstreamNetworkMonitor.selectPreferredUpstreamType(
final NetworkState ns = mUpstreamNetworkMonitor.selectPreferredUpstreamType(
mConfig.preferredUpstreamIfaceTypes);
if (upstreamType == ConnectivityManager.TYPE_NONE) {
if (ns == null) {
if (tryCell) {
mUpstreamNetworkMonitor.registerMobileNetworkRequest();
// We think mobile should be coming up; don't set a retry.
@@ -1259,40 +1259,30 @@ public class Tethering extends BaseNetworkObserver {
sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
}
}
setUpstreamByType(upstreamType);
setUpstreamByType(ns);
}
protected void setUpstreamByType(int upType) {
final ConnectivityManager cm = getConnectivityManager();
Network network = null;
protected void setUpstreamByType(NetworkState ns) {
String iface = null;
if (upType != ConnectivityManager.TYPE_NONE) {
LinkProperties linkProperties = cm.getLinkProperties(upType);
if (linkProperties != null) {
// Find the interface with the default IPv4 route. It may be the
// interface described by linkProperties, or one of the interfaces
// stacked on top of it.
Log.i(TAG, "Finding IPv4 upstream interface on: " + linkProperties);
RouteInfo ipv4Default = RouteInfo.selectBestRoute(
linkProperties.getAllRoutes(), Inet4Address.ANY);
if (ipv4Default != null) {
iface = ipv4Default.getInterface();
Log.i(TAG, "Found interface " + ipv4Default.getInterface());
} else {
Log.i(TAG, "No IPv4 upstream interface, giving up.");
}
}
if (iface != null) {
network = cm.getNetworkForType(upType);
if (network == null) {
Log.e(TAG, "No Network for upstream type " + upType + "!");
}
setDnsForwarders(network, linkProperties);
if (ns != null && ns.linkProperties != null) {
// Find the interface with the default IPv4 route. It may be the
// interface described by linkProperties, or one of the interfaces
// stacked on top of it.
Log.i(TAG, "Finding IPv4 upstream interface on: " + ns.linkProperties);
RouteInfo ipv4Default = RouteInfo.selectBestRoute(
ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
if (ipv4Default != null) {
iface = ipv4Default.getInterface();
Log.i(TAG, "Found interface " + ipv4Default.getInterface());
} else {
Log.i(TAG, "No IPv4 upstream interface, giving up.");
}
}
if (iface != null) {
setDnsForwarders(ns.network, ns.linkProperties);
}
notifyTetheredOfNewUpstreamIface(iface);
NetworkState ns = mUpstreamNetworkMonitor.lookup(network);
if (ns != null && pertainsToCurrentUpstream(ns)) {
// If we already have NetworkState for this network examine
// it immediately, because there likely will be no second

View File

@@ -174,10 +174,6 @@ public class UpstreamNetworkMonitor {
mMobileNetworkCallback = null;
}
public NetworkState lookup(Network network) {
return (network != null) ? mNetworkMap.get(network) : null;
}
// So many TODOs here, but chief among them is: make this functionality an
// integral part of this class such that whenever a higher priority network
// becomes available and useful we (a) file a request to keep it up as
@@ -185,7 +181,7 @@ public class UpstreamNetworkMonitor {
// passing LinkProperties up to Tethering).
//
// Next TODO: return NetworkState instead of just the type.
public int selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
mNetworkMap.values(), preferredTypes);
@@ -210,7 +206,7 @@ public class UpstreamNetworkMonitor {
break;
}
return typeStatePair.type;
return typeStatePair.ns;
}
private void handleAvailable(int callbackType, Network network) {

View File

@@ -47,6 +47,7 @@ import android.net.IConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.util.SharedLog;
import android.support.test.filters.SmallTest;
@@ -253,31 +254,32 @@ public class UpstreamNetworkMonitorTest {
mUNM.start();
// There are no networks, so there is nothing to select.
assertEquals(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
wifiAgent.fakeConnect();
// WiFi is up, we should prefer it.
assertEquals(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
wifiAgent.fakeDisconnect();
// There are no networks, so there is nothing to select.
assertEquals(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
cellAgent.fakeConnect();
assertEquals(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
preferredTypes.add(TYPE_MOBILE_DUN);
// This is coupled with preferred types in TetheringConfiguration.
mUNM.updateMobileRequiresDun(true);
// DUN is available, but only use regular cell: no upstream selected.
assertEquals(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
preferredTypes.remove(TYPE_MOBILE_DUN);
// No WiFi, but our preferred flavour of cell is up.
preferredTypes.add(TYPE_MOBILE_HIPRI);
// This is coupled with preferred types in TetheringConfiguration.
mUNM.updateMobileRequiresDun(false);
assertEquals(TYPE_MOBILE_HIPRI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
mUNM.selectPreferredUpstreamType(preferredTypes));
// Check to see we filed an explicit request.
assertEquals(1, mCM.requested.size());
NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
@@ -286,25 +288,26 @@ public class UpstreamNetworkMonitorTest {
wifiAgent.fakeConnect();
// WiFi is up, and we should prefer it over cell.
assertEquals(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertEquals(0, mCM.requested.size());
preferredTypes.remove(TYPE_MOBILE_HIPRI);
preferredTypes.add(TYPE_MOBILE_DUN);
// This is coupled with preferred types in TetheringConfiguration.
mUNM.updateMobileRequiresDun(true);
assertEquals(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
dunAgent.fakeConnect();
// WiFi is still preferred.
assertEquals(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
// WiFi goes down, cell and DUN are still up but only DUN is preferred.
wifiAgent.fakeDisconnect();
assertEquals(TYPE_MOBILE_DUN, mUNM.selectPreferredUpstreamType(preferredTypes));
assertSatisfiesLegacyType(TYPE_MOBILE_DUN,
mUNM.selectPreferredUpstreamType(preferredTypes));
// Check to see we filed an explicit request.
assertEquals(1, mCM.requested.size());
netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
@@ -312,6 +315,16 @@ public class UpstreamNetworkMonitorTest {
assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
}
private void assertSatisfiesLegacyType(int legacyType, NetworkState ns) {
if (legacyType == TYPE_NONE) {
assertTrue(ns == null);
return;
}
final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
assertTrue(nc.satisfiedByNetworkCapabilities(ns.networkCapabilities));
}
private void assertUpstreamTypeRequested(int upstreamType) throws Exception {
assertEquals(1, mCM.requested.size());
assertEquals(1, mCM.legacyTypeMap.size());