Merge "Move findPreferredUpstreamType into UNM" am: 32703994fe
am: 8bc87070f9
Change-Id: Ia215e55b69b856f5511e5d4f852e39fa6c11462e
This commit is contained in:
@@ -1249,8 +1249,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
|||||||
protected void chooseUpstreamType(boolean tryCell) {
|
protected void chooseUpstreamType(boolean tryCell) {
|
||||||
updateConfiguration(); // TODO - remove?
|
updateConfiguration(); // TODO - remove?
|
||||||
|
|
||||||
final int upstreamType = findPreferredUpstreamType(
|
final int upstreamType = mUpstreamNetworkMonitor.selectPreferredUpstreamType(
|
||||||
getConnectivityManager(), mConfig);
|
mConfig.preferredUpstreamIfaceTypes);
|
||||||
if (upstreamType == ConnectivityManager.TYPE_NONE) {
|
if (upstreamType == ConnectivityManager.TYPE_NONE) {
|
||||||
if (tryCell) {
|
if (tryCell) {
|
||||||
mUpstreamNetworkMonitor.registerMobileNetworkRequest();
|
mUpstreamNetworkMonitor.registerMobileNetworkRequest();
|
||||||
@@ -1262,58 +1262,6 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
|||||||
setUpstreamByType(upstreamType);
|
setUpstreamByType(upstreamType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this function into UpstreamNetworkMonitor.
|
|
||||||
protected int findPreferredUpstreamType(ConnectivityManager cm,
|
|
||||||
TetheringConfiguration cfg) {
|
|
||||||
int upType = ConnectivityManager.TYPE_NONE;
|
|
||||||
|
|
||||||
if (VDBG) {
|
|
||||||
Log.d(TAG, "chooseUpstreamType has upstream iface types:");
|
|
||||||
for (Integer netType : cfg.preferredUpstreamIfaceTypes) {
|
|
||||||
Log.d(TAG, " " + netType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Integer netType : cfg.preferredUpstreamIfaceTypes) {
|
|
||||||
NetworkInfo info = cm.getNetworkInfo(netType.intValue());
|
|
||||||
// TODO: if the network is suspended we should consider
|
|
||||||
// that to be the same as connected here.
|
|
||||||
if ((info != null) && info.isConnected()) {
|
|
||||||
upType = netType.intValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final int preferredUpstreamMobileApn = cfg.isDunRequired
|
|
||||||
? ConnectivityManager.TYPE_MOBILE_DUN
|
|
||||||
: ConnectivityManager.TYPE_MOBILE_HIPRI;
|
|
||||||
mLog.log(String.format(
|
|
||||||
"findPreferredUpstreamType(), preferredApn=%s, got type=%s",
|
|
||||||
getNetworkTypeName(preferredUpstreamMobileApn),
|
|
||||||
getNetworkTypeName(upType)));
|
|
||||||
|
|
||||||
switch (upType) {
|
|
||||||
case ConnectivityManager.TYPE_MOBILE_DUN:
|
|
||||||
case ConnectivityManager.TYPE_MOBILE_HIPRI:
|
|
||||||
// If we're on DUN, put our own grab on it.
|
|
||||||
mUpstreamNetworkMonitor.registerMobileNetworkRequest();
|
|
||||||
break;
|
|
||||||
case ConnectivityManager.TYPE_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* If we've found an active upstream connection that's not DUN/HIPRI
|
|
||||||
* we should stop any outstanding DUN/HIPRI start requests.
|
|
||||||
*
|
|
||||||
* If we found NONE we don't want to do this as we want any previous
|
|
||||||
* requests to keep trying to bring up something we can use.
|
|
||||||
*/
|
|
||||||
mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return upType;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setUpstreamByType(int upType) {
|
protected void setUpstreamByType(int upType) {
|
||||||
final ConnectivityManager cm = getConnectivityManager();
|
final ConnectivityManager cm = getConnectivityManager();
|
||||||
Network network = null;
|
Network network = null;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.connectivity.tethering;
|
package com.android.server.connectivity.tethering;
|
||||||
|
|
||||||
|
import static android.net.ConnectivityManager.getNetworkTypeName;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||||
|
|
||||||
@@ -176,6 +178,41 @@ public class UpstreamNetworkMonitor {
|
|||||||
return (network != null) ? mNetworkMap.get(network) : null;
|
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
|
||||||
|
// necessary and (b) change all upstream tracking state accordingly (by
|
||||||
|
// passing LinkProperties up to Tethering).
|
||||||
|
//
|
||||||
|
// Next TODO: return NetworkState instead of just the type.
|
||||||
|
public int selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
|
||||||
|
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
|
||||||
|
mNetworkMap.values(), preferredTypes);
|
||||||
|
|
||||||
|
mLog.log("preferred upstream type: " + getNetworkTypeName(typeStatePair.type));
|
||||||
|
|
||||||
|
switch (typeStatePair.type) {
|
||||||
|
case TYPE_MOBILE_DUN:
|
||||||
|
case TYPE_MOBILE_HIPRI:
|
||||||
|
// If we're on DUN, put our own grab on it.
|
||||||
|
registerMobileNetworkRequest();
|
||||||
|
break;
|
||||||
|
case TYPE_NONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* If we've found an active upstream connection that's not DUN/HIPRI
|
||||||
|
* we should stop any outstanding DUN/HIPRI start requests.
|
||||||
|
*
|
||||||
|
* If we found NONE we don't want to do this as we want any previous
|
||||||
|
* requests to keep trying to bring up something we can use.
|
||||||
|
*/
|
||||||
|
releaseMobileNetworkRequest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeStatePair.type;
|
||||||
|
}
|
||||||
|
|
||||||
private void handleAvailable(int callbackType, Network network) {
|
private void handleAvailable(int callbackType, Network network) {
|
||||||
if (VDBG) Log.d(TAG, "EVENT_ON_AVAILABLE for " + network);
|
if (VDBG) Log.d(TAG, "EVENT_ON_AVAILABLE for " + network);
|
||||||
|
|
||||||
@@ -365,4 +402,37 @@ public class UpstreamNetworkMonitor {
|
|||||||
private void notifyTarget(int which, NetworkState netstate) {
|
private void notifyTarget(int which, NetworkState netstate) {
|
||||||
mTarget.sendMessage(mWhat, which, 0, netstate);
|
mTarget.sendMessage(mWhat, which, 0, netstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static private class TypeStatePair {
|
||||||
|
public int type = TYPE_NONE;
|
||||||
|
public NetworkState ns = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static private TypeStatePair findFirstAvailableUpstreamByType(
|
||||||
|
Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes) {
|
||||||
|
final TypeStatePair result = new TypeStatePair();
|
||||||
|
|
||||||
|
for (int type : preferredTypes) {
|
||||||
|
NetworkCapabilities nc;
|
||||||
|
try {
|
||||||
|
nc = ConnectivityManager.networkCapabilitiesForType(type);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " +
|
||||||
|
ConnectivityManager.getNetworkTypeName(type));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NetworkState value : netStates) {
|
||||||
|
if (!nc.satisfiedByNetworkCapabilities(value.networkCapabilities)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.type = type;
|
||||||
|
result.ns = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -368,7 +368,6 @@ public class TetheringTest {
|
|||||||
any(NetworkCallback.class), any(Handler.class));
|
any(NetworkCallback.class), any(Handler.class));
|
||||||
// In tethering mode, in the default configuration, an explicit request
|
// In tethering mode, in the default configuration, an explicit request
|
||||||
// for a mobile network is also made.
|
// for a mobile network is also made.
|
||||||
verify(mConnectivityManager, atLeastOnce()).getNetworkInfo(anyInt());
|
|
||||||
verify(mConnectivityManager, times(1)).requestNetwork(
|
verify(mConnectivityManager, times(1)).requestNetwork(
|
||||||
any(NetworkRequest.class), any(NetworkCallback.class), eq(0), anyInt(),
|
any(NetworkRequest.class), any(NetworkCallback.class), eq(0), anyInt(),
|
||||||
any(Handler.class));
|
any(Handler.class));
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ package com.android.server.connectivity.tethering;
|
|||||||
|
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -59,6 +64,7 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -240,6 +246,72 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
assertFalse(mUNM.mobileNetworkRequested());
|
assertFalse(mUNM.mobileNetworkRequested());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectPreferredUpstreamType() throws Exception {
|
||||||
|
final Collection<Integer> preferredTypes = new ArrayList<>();
|
||||||
|
preferredTypes.add(TYPE_WIFI);
|
||||||
|
|
||||||
|
mUNM.start();
|
||||||
|
// There are no networks, so there is nothing to select.
|
||||||
|
assertEquals(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));
|
||||||
|
wifiAgent.fakeDisconnect();
|
||||||
|
// There are no networks, so there is nothing to select.
|
||||||
|
assertEquals(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
|
|
||||||
|
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
||||||
|
cellAgent.fakeConnect();
|
||||||
|
assertEquals(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));
|
||||||
|
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));
|
||||||
|
// Check to see we filed an explicit request.
|
||||||
|
assertEquals(1, mCM.requested.size());
|
||||||
|
NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
|
||||||
|
assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
|
||||||
|
assertFalse(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
|
||||||
|
|
||||||
|
wifiAgent.fakeConnect();
|
||||||
|
// WiFi is up, and we should prefer it over cell.
|
||||||
|
assertEquals(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));
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// WiFi goes down, cell and DUN are still up but only DUN is preferred.
|
||||||
|
wifiAgent.fakeDisconnect();
|
||||||
|
assertEquals(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];
|
||||||
|
assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
|
||||||
|
assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
|
||||||
|
}
|
||||||
|
|
||||||
private void assertUpstreamTypeRequested(int upstreamType) throws Exception {
|
private void assertUpstreamTypeRequested(int upstreamType) throws Exception {
|
||||||
assertEquals(1, mCM.requested.size());
|
assertEquals(1, mCM.requested.size());
|
||||||
assertEquals(1, mCM.legacyTypeMap.size());
|
assertEquals(1, mCM.legacyTypeMap.size());
|
||||||
@@ -254,6 +326,8 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
|
public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
|
||||||
public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
|
public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
|
||||||
|
|
||||||
|
private int mNetworkId = 100;
|
||||||
|
|
||||||
public TestConnectivityManager(Context ctx, IConnectivityManager svc) {
|
public TestConnectivityManager(Context ctx, IConnectivityManager svc) {
|
||||||
super(ctx, svc);
|
super(ctx, svc);
|
||||||
}
|
}
|
||||||
@@ -287,6 +361,8 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getNetworkId() { return ++mNetworkId; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
|
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
|
||||||
assertFalse(allCallbacks.containsKey(cb));
|
assertFalse(allCallbacks.containsKey(cb));
|
||||||
@@ -360,6 +436,35 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TestNetworkAgent {
|
||||||
|
public final TestConnectivityManager cm;
|
||||||
|
public final Network networkId;
|
||||||
|
public final int transportType;
|
||||||
|
public final NetworkCapabilities networkCapabilities;
|
||||||
|
|
||||||
|
public TestNetworkAgent(TestConnectivityManager cm, int transportType) {
|
||||||
|
this.cm = cm;
|
||||||
|
this.networkId = new Network(cm.getNetworkId());
|
||||||
|
this.transportType = transportType;
|
||||||
|
networkCapabilities = new NetworkCapabilities();
|
||||||
|
networkCapabilities.addTransportType(transportType);
|
||||||
|
networkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fakeConnect() {
|
||||||
|
for (NetworkCallback cb : cm.listening.keySet()) {
|
||||||
|
cb.onAvailable(networkId);
|
||||||
|
cb.onCapabilitiesChanged(networkId, copy(networkCapabilities));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fakeDisconnect() {
|
||||||
|
for (NetworkCallback cb : cm.listening.keySet()) {
|
||||||
|
cb.onLost(networkId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestStateMachine extends StateMachine {
|
public static class TestStateMachine extends StateMachine {
|
||||||
public final ArrayList<Message> messages = new ArrayList<>();
|
public final ArrayList<Message> messages = new ArrayList<>();
|
||||||
private final State mLoggingState = new LoggingState();
|
private final State mLoggingState = new LoggingState();
|
||||||
@@ -382,4 +487,8 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NetworkCapabilities copy(NetworkCapabilities nc) {
|
||||||
|
return new NetworkCapabilities(nc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user