Merge "[Tether05] Migrate UpstreamNetworkMonitor into module"

This commit is contained in:
Mark Chien
2019-10-31 13:05:32 +00:00
committed by Gerrit Code Review
6 changed files with 79 additions and 45 deletions

View File

@@ -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",
],
}

View File

@@ -23,7 +23,6 @@
<application
android:label="Tethering"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:usesCleartextTraffic="true">
android:directBootAware="true">
</application>
</manifest>

View File

@@ -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

View File

@@ -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) {

View File

@@ -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",

View File

@@ -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);