Merge "[Tether05] Migrate UpstreamNetworkMonitor into module"
am: 259fdbb0b3
Change-Id: I64ff858bb8a5ff63046f46a4cefd3ff10695f619
This commit is contained in:
@@ -72,6 +72,7 @@ filegroup {
|
||||
srcs: [
|
||||
"src/com/android/server/connectivity/tethering/EntitlementManager.java",
|
||||
"src/com/android/server/connectivity/tethering/TetheringConfiguration.java",
|
||||
"src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -84,5 +85,6 @@ filegroup {
|
||||
"src/android/net/ip/IpServer.java",
|
||||
"src/android/net/ip/RouterAdvertisementDaemon.java",
|
||||
"src/android/net/util/InterfaceSet.java",
|
||||
"src/android/net/util/PrefixUtils.java",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
<application
|
||||
android:label="Tethering"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
android:directBootAware="true"
|
||||
android:usesCleartextTraffic="true">
|
||||
android:directBootAware="true">
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -42,16 +42,19 @@ public class PrefixUtils {
|
||||
|
||||
public static final IpPrefix DEFAULT_WIFI_P2P_PREFIX = pfx("192.168.49.0/24");
|
||||
|
||||
/** Get non forwardable prefixes. */
|
||||
public static Set<IpPrefix> getNonForwardablePrefixes() {
|
||||
final HashSet<IpPrefix> prefixes = new HashSet<>();
|
||||
addNonForwardablePrefixes(prefixes);
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
/** Add non forwardable prefixes. */
|
||||
public static void addNonForwardablePrefixes(Set<IpPrefix> prefixes) {
|
||||
Collections.addAll(prefixes, MIN_NON_FORWARDABLE_PREFIXES);
|
||||
}
|
||||
|
||||
/** Get local prefixes from |lp|. */
|
||||
public static Set<IpPrefix> localPrefixesFrom(LinkProperties lp) {
|
||||
final HashSet<IpPrefix> localPrefixes = new HashSet<>();
|
||||
if (lp == null) return localPrefixes;
|
||||
@@ -66,10 +69,12 @@ public class PrefixUtils {
|
||||
return localPrefixes;
|
||||
}
|
||||
|
||||
/** Convert LinkAddress |addr| to IpPrefix. */
|
||||
public static IpPrefix asIpPrefix(LinkAddress addr) {
|
||||
return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
|
||||
}
|
||||
|
||||
/** Convert InetAddress |ip| to IpPrefix. */
|
||||
public static IpPrefix ipAddressAsPrefix(InetAddress ip) {
|
||||
final int bitLength = (ip instanceof Inet4Address)
|
||||
? NetworkConstants.IPV4_ADDR_BITS
|
||||
@@ -146,6 +146,7 @@ public class UpstreamNetworkMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
/** Listen all networks. */
|
||||
public void startObserveAllNetworks() {
|
||||
stop();
|
||||
|
||||
@@ -155,6 +156,13 @@ public class UpstreamNetworkMonitor {
|
||||
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop tracking candidate tethering upstreams and release mobile network request.
|
||||
* Note: this function is used when tethering is stopped because tethering do not need to
|
||||
* choose upstream anymore. But it would not stop default network tracking because
|
||||
* EntitlementManager may need to know default network to decide whether to request entitlement
|
||||
* check even tethering is not active yet.
|
||||
*/
|
||||
public void stop() {
|
||||
releaseMobileNetworkRequest();
|
||||
|
||||
@@ -165,6 +173,7 @@ public class UpstreamNetworkMonitor {
|
||||
mNetworkMap.clear();
|
||||
}
|
||||
|
||||
/** Setup or teardown DUN connection according to |dunRequired|. */
|
||||
public void updateMobileRequiresDun(boolean dunRequired) {
|
||||
final boolean valueChanged = (mDunRequired != dunRequired);
|
||||
mDunRequired = dunRequired;
|
||||
@@ -174,10 +183,12 @@ public class UpstreamNetworkMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether mobile network is requested. */
|
||||
public boolean mobileNetworkRequested() {
|
||||
return (mMobileNetworkCallback != null);
|
||||
}
|
||||
|
||||
/** Request mobile network if mobile upstream is permitted. */
|
||||
public void registerMobileNetworkRequest() {
|
||||
if (!isCellularUpstreamPermitted()) {
|
||||
mLog.i("registerMobileNetworkRequest() is not permitted");
|
||||
@@ -209,6 +220,7 @@ public class UpstreamNetworkMonitor {
|
||||
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
|
||||
}
|
||||
|
||||
/** Release mobile network request. */
|
||||
public void releaseMobileNetworkRequest() {
|
||||
if (mMobileNetworkCallback == null) return;
|
||||
|
||||
@@ -221,6 +233,9 @@ public class UpstreamNetworkMonitor {
|
||||
// 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).
|
||||
/**
|
||||
* Select the first available network from |perferredTypes|.
|
||||
*/
|
||||
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
|
||||
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
|
||||
mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
|
||||
@@ -254,7 +269,11 @@ public class UpstreamNetworkMonitor {
|
||||
return typeStatePair.ns;
|
||||
}
|
||||
|
||||
// Returns null if no current upstream available.
|
||||
/**
|
||||
* Get current preferred upstream network. If default network is cellular and DUN is required,
|
||||
* preferred upstream would be DUN otherwise preferred upstream is the same as default network.
|
||||
* Returns null if no current upstream is available.
|
||||
*/
|
||||
public NetworkState getCurrentPreferredUpstream() {
|
||||
final NetworkState dfltState = (mDefaultInternetNetwork != null)
|
||||
? mNetworkMap.get(mDefaultInternetNetwork)
|
||||
@@ -270,10 +289,12 @@ public class UpstreamNetworkMonitor {
|
||||
return findFirstDunNetwork(mNetworkMap.values());
|
||||
}
|
||||
|
||||
/** Tell UpstreamNetworkMonitor which network is the current upstream of tethering. */
|
||||
public void setCurrentUpstream(Network upstream) {
|
||||
mTetheringUpstreamNetwork = upstream;
|
||||
}
|
||||
|
||||
/** Return local prefixes. */
|
||||
public Set<IpPrefix> getLocalPrefixes() {
|
||||
return (Set<IpPrefix>) mLocalPrefixes.clone();
|
||||
}
|
||||
@@ -501,8 +522,8 @@ public class UpstreamNetworkMonitor {
|
||||
try {
|
||||
nc = ConnectivityManager.networkCapabilitiesForType(type);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " +
|
||||
ConnectivityManager.getNetworkTypeName(type));
|
||||
Log.e(TAG, "No NetworkCapabilities mapping for legacy type: "
|
||||
+ ConnectivityManager.getNetworkTypeName(type));
|
||||
continue;
|
||||
}
|
||||
if (!isCellularUpstreamPermitted && isCellular(nc)) {
|
||||
@@ -547,18 +568,18 @@ public class UpstreamNetworkMonitor {
|
||||
}
|
||||
|
||||
private static boolean isCellular(NetworkCapabilities nc) {
|
||||
return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR) &&
|
||||
nc.hasCapability(NET_CAPABILITY_NOT_VPN);
|
||||
return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR)
|
||||
&& nc.hasCapability(NET_CAPABILITY_NOT_VPN);
|
||||
}
|
||||
|
||||
private static boolean hasCapability(NetworkState ns, int netCap) {
|
||||
return (ns != null) && (ns.networkCapabilities != null) &&
|
||||
ns.networkCapabilities.hasCapability(netCap);
|
||||
return (ns != null) && (ns.networkCapabilities != null)
|
||||
&& ns.networkCapabilities.hasCapability(netCap);
|
||||
}
|
||||
|
||||
private static boolean isNetworkUsableAndNotCellular(NetworkState ns) {
|
||||
return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null) &&
|
||||
!isCellular(ns.networkCapabilities);
|
||||
return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
|
||||
&& !isCellular(ns.networkCapabilities);
|
||||
}
|
||||
|
||||
private static NetworkState findFirstDunNetwork(Iterable<NetworkState> netStates) {
|
||||
@@ -47,6 +47,7 @@ filegroup {
|
||||
srcs: [
|
||||
"src/com/android/server/connectivity/tethering/EntitlementManagerTest.java",
|
||||
"src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java",
|
||||
"src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java",
|
||||
"src/android/net/dhcp/DhcpServingParamsParcelExtTest.java",
|
||||
"src/android/net/ip/IpServerTest.java",
|
||||
"src/android/net/util/InterfaceSetTest.java",
|
||||
|
||||
@@ -87,7 +87,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
// Actual contents of the request don't matter for this test. The lack of
|
||||
// any specific TRANSPORT_* is sufficient to identify this request.
|
||||
private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
|
||||
private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private EntitlementManager mEntitleMgr;
|
||||
@@ -140,7 +140,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
@Test
|
||||
public void testDefaultNetworkIsTracked() throws Exception {
|
||||
assertTrue(mCM.hasNoCallbacks());
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
|
||||
mUNM.startObserveAllNetworks();
|
||||
assertEquals(1, mCM.trackingDefault.size());
|
||||
@@ -153,7 +153,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
public void testListensForAllNetworks() throws Exception {
|
||||
assertTrue(mCM.listening.isEmpty());
|
||||
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
mUNM.startObserveAllNetworks();
|
||||
assertFalse(mCM.listening.isEmpty());
|
||||
assertTrue(mCM.isListeningForAll());
|
||||
@@ -164,9 +164,9 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
@Test
|
||||
public void testCallbacksRegistered() {
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
verify(mCM, times(1)).requestNetwork(
|
||||
eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
|
||||
eq(sDefaultRequest), any(NetworkCallback.class), any(Handler.class));
|
||||
mUNM.startObserveAllNetworks();
|
||||
verify(mCM, times(1)).registerNetworkCallback(
|
||||
any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
|
||||
@@ -191,7 +191,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
mUNM.registerMobileNetworkRequest();
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
|
||||
assertFalse(mCM.isDunRequested());
|
||||
assertFalse(isDunRequested());
|
||||
|
||||
mUNM.stop();
|
||||
assertFalse(mUNM.mobileNetworkRequested());
|
||||
@@ -217,7 +217,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
||||
assertTrue(mCM.isDunRequested());
|
||||
assertTrue(isDunRequested());
|
||||
|
||||
// Try a few things that must not result in any state change.
|
||||
mUNM.registerMobileNetworkRequest();
|
||||
@@ -226,7 +226,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
||||
assertTrue(mCM.isDunRequested());
|
||||
assertTrue(isDunRequested());
|
||||
|
||||
mUNM.stop();
|
||||
verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
|
||||
@@ -250,7 +250,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
mUNM.registerMobileNetworkRequest();
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
||||
assertTrue(mCM.isDunRequested());
|
||||
assertTrue(isDunRequested());
|
||||
|
||||
mUNM.stop();
|
||||
assertFalse(mUNM.mobileNetworkRequested());
|
||||
@@ -266,17 +266,17 @@ public class UpstreamNetworkMonitorTest {
|
||||
mUNM.registerMobileNetworkRequest();
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
|
||||
assertFalse(mCM.isDunRequested());
|
||||
assertFalse(isDunRequested());
|
||||
mUNM.updateMobileRequiresDun(true);
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
|
||||
assertTrue(mCM.isDunRequested());
|
||||
assertTrue(isDunRequested());
|
||||
|
||||
// Test going from DUN to no-DUN correctly re-registers callbacks.
|
||||
mUNM.updateMobileRequiresDun(false);
|
||||
assertTrue(mUNM.mobileNetworkRequested());
|
||||
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
|
||||
assertFalse(mCM.isDunRequested());
|
||||
assertFalse(isDunRequested());
|
||||
|
||||
mUNM.stop();
|
||||
assertFalse(mUNM.mobileNetworkRequested());
|
||||
@@ -287,7 +287,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
final Collection<Integer> preferredTypes = new ArrayList<>();
|
||||
preferredTypes.add(TYPE_WIFI);
|
||||
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
mUNM.startObserveAllNetworks();
|
||||
// There are no networks, so there is nothing to select.
|
||||
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||
@@ -369,7 +369,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
@Test
|
||||
public void testGetCurrentPreferredUpstream() throws Exception {
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
mUNM.startObserveAllNetworks();
|
||||
mUNM.updateMobileRequiresDun(false);
|
||||
|
||||
@@ -418,7 +418,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
|
||||
@Test
|
||||
public void testLocalPrefixes() throws Exception {
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
mUNM.startObserveAllNetworks();
|
||||
|
||||
// [0] Test minimum set of local prefixes.
|
||||
@@ -431,13 +431,13 @@ public class UpstreamNetworkMonitorTest {
|
||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
||||
final LinkProperties wifiLp = wifiAgent.linkProperties;
|
||||
wifiLp.setInterfaceName("wlan0");
|
||||
final String[] WIFI_ADDRS = {
|
||||
final String[] wifi_addrs = {
|
||||
"fe80::827a:bfff:fe6f:374d", "100.112.103.18",
|
||||
"2001:db8:4:fd00:827a:bfff:fe6f:374d",
|
||||
"2001:db8:4:fd00:6dea:325a:fdae:4ef4",
|
||||
"fd6a:a640:60bf:e985::123", // ULA address for good measure.
|
||||
};
|
||||
for (String addrStr : WIFI_ADDRS) {
|
||||
for (String addrStr : wifi_addrs) {
|
||||
final String cidr = addrStr.contains(":") ? "/64" : "/20";
|
||||
wifiLp.addLinkAddress(new LinkAddress(addrStr + cidr));
|
||||
}
|
||||
@@ -458,10 +458,10 @@ public class UpstreamNetworkMonitorTest {
|
||||
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
|
||||
final LinkProperties cellLp = cellAgent.linkProperties;
|
||||
cellLp.setInterfaceName("rmnet_data0");
|
||||
final String[] CELL_ADDRS = {
|
||||
final String[] cell_addrs = {
|
||||
"10.102.211.48", "2001:db8:0:1:b50e:70d9:10c9:433d",
|
||||
};
|
||||
for (String addrStr : CELL_ADDRS) {
|
||||
for (String addrStr : cell_addrs) {
|
||||
final String cidr = addrStr.contains(":") ? "/64" : "/27";
|
||||
cellLp.addLinkAddress(new LinkAddress(addrStr + cidr));
|
||||
}
|
||||
@@ -481,10 +481,10 @@ public class UpstreamNetworkMonitorTest {
|
||||
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
|
||||
final LinkProperties dunLp = dunAgent.linkProperties;
|
||||
dunLp.setInterfaceName("rmnet_data1");
|
||||
final String[] DUN_ADDRS = {
|
||||
final String[] dun_addrs = {
|
||||
"192.0.2.48", "2001:db8:1:2:b50e:70d9:10c9:433d",
|
||||
};
|
||||
for (String addrStr : DUN_ADDRS) {
|
||||
for (String addrStr : dun_addrs) {
|
||||
final String cidr = addrStr.contains(":") ? "/64" : "/27";
|
||||
dunLp.addLinkAddress(new LinkAddress(addrStr + cidr));
|
||||
}
|
||||
@@ -525,7 +525,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
// Mobile has higher pirority than wifi.
|
||||
preferredTypes.add(TYPE_MOBILE_HIPRI);
|
||||
preferredTypes.add(TYPE_WIFI);
|
||||
mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
|
||||
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
|
||||
mUNM.startObserveAllNetworks();
|
||||
// Setup wifi and make wifi as default network.
|
||||
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
|
||||
@@ -556,6 +556,15 @@ public class UpstreamNetworkMonitorTest {
|
||||
mCM.legacyTypeMap.values().iterator().next());
|
||||
}
|
||||
|
||||
private boolean isDunRequested() {
|
||||
for (NetworkRequest req : mCM.requested.values()) {
|
||||
if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class TestConnectivityManager extends ConnectivityManager {
|
||||
public Map<NetworkCallback, Handler> allCallbacks = new HashMap<>();
|
||||
public Set<NetworkCallback> trackingDefault = new HashSet<>();
|
||||
@@ -598,17 +607,10 @@ public class UpstreamNetworkMonitorTest {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isDunRequested() {
|
||||
for (NetworkRequest req : requested.values()) {
|
||||
if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
int getNetworkId() {
|
||||
return ++mNetworkId;
|
||||
}
|
||||
|
||||
int getNetworkId() { return ++mNetworkId; }
|
||||
|
||||
void makeDefaultNetwork(TestNetworkAgent agent) {
|
||||
if (Objects.equals(defaultNetwork, agent)) return;
|
||||
|
||||
@@ -630,7 +632,7 @@ public class UpstreamNetworkMonitorTest {
|
||||
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
|
||||
assertFalse(allCallbacks.containsKey(cb));
|
||||
allCallbacks.put(cb, h);
|
||||
if (mDefaultRequest.equals(req)) {
|
||||
if (sDefaultRequest.equals(req)) {
|
||||
assertFalse(trackingDefault.contains(cb));
|
||||
trackingDefault.add(cb);
|
||||
} else {
|
||||
@@ -749,9 +751,13 @@ public class UpstreamNetworkMonitorTest {
|
||||
private final State mLoggingState = new LoggingState();
|
||||
|
||||
class LoggingState extends State {
|
||||
@Override public void enter() { messages.clear(); }
|
||||
@Override public void enter() {
|
||||
messages.clear();
|
||||
}
|
||||
|
||||
@Override public void exit() { messages.clear(); }
|
||||
@Override public void exit() {
|
||||
messages.clear();
|
||||
}
|
||||
|
||||
@Override public boolean processMessage(Message msg) {
|
||||
messages.add(msg);
|
||||
Reference in New Issue
Block a user