Loading services/core/java/com/android/server/connectivity/Tethering.java +19 −29 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -1259,22 +1259,18 @@ 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) { 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: " + linkProperties); Log.i(TAG, "Finding IPv4 upstream interface on: " + ns.linkProperties); RouteInfo ipv4Default = RouteInfo.selectBestRoute( linkProperties.getAllRoutes(), Inet4Address.ANY); ns.linkProperties.getAllRoutes(), Inet4Address.ANY); if (ipv4Default != null) { iface = ipv4Default.getInterface(); Log.i(TAG, "Found interface " + ipv4Default.getInterface()); Loading @@ -1284,15 +1280,9 @@ public class Tethering extends BaseNetworkObserver { } if (iface != null) { network = cm.getNetworkForType(upType); if (network == null) { Log.e(TAG, "No Network for upstream type " + upType + "!"); } setDnsForwarders(network, linkProperties); } 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 Loading services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +2 −6 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading @@ -210,7 +206,7 @@ public class UpstreamNetworkMonitor { break; } return typeStatePair.type; return typeStatePair.ns; } private void handleAvailable(int callbackType, Network network) { Loading tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +23 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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]; Loading @@ -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()); Loading Loading
services/core/java/com/android/server/connectivity/Tethering.java +19 −29 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -1259,22 +1259,18 @@ 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) { 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: " + linkProperties); Log.i(TAG, "Finding IPv4 upstream interface on: " + ns.linkProperties); RouteInfo ipv4Default = RouteInfo.selectBestRoute( linkProperties.getAllRoutes(), Inet4Address.ANY); ns.linkProperties.getAllRoutes(), Inet4Address.ANY); if (ipv4Default != null) { iface = ipv4Default.getInterface(); Log.i(TAG, "Found interface " + ipv4Default.getInterface()); Loading @@ -1284,15 +1280,9 @@ public class Tethering extends BaseNetworkObserver { } if (iface != null) { network = cm.getNetworkForType(upType); if (network == null) { Log.e(TAG, "No Network for upstream type " + upType + "!"); } setDnsForwarders(network, linkProperties); } 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 Loading
services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +2 −6 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading @@ -210,7 +206,7 @@ public class UpstreamNetworkMonitor { break; } return typeStatePair.type; return typeStatePair.ns; } private void handleAvailable(int callbackType, Network network) { Loading
tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +23 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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]; Loading @@ -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()); Loading