Merge "Add UpstreamNetworkState for tethering"
This commit is contained in:
@@ -21,7 +21,6 @@ import android.net.LinkAddress;
|
|||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.ip.IpServer;
|
import android.net.ip.IpServer;
|
||||||
import android.net.util.NetworkConstants;
|
import android.net.util.NetworkConstants;
|
||||||
@@ -72,7 +71,7 @@ public class IPv6TetheringCoordinator {
|
|||||||
private final LinkedList<Downstream> mActiveDownstreams;
|
private final LinkedList<Downstream> mActiveDownstreams;
|
||||||
private final byte[] mUniqueLocalPrefix;
|
private final byte[] mUniqueLocalPrefix;
|
||||||
private short mNextSubnetId;
|
private short mNextSubnetId;
|
||||||
private NetworkState mUpstreamNetworkState;
|
private UpstreamNetworkState mUpstreamNetworkState;
|
||||||
|
|
||||||
public IPv6TetheringCoordinator(ArrayList<IpServer> notifyList, SharedLog log) {
|
public IPv6TetheringCoordinator(ArrayList<IpServer> notifyList, SharedLog log) {
|
||||||
mNotifyList = notifyList;
|
mNotifyList = notifyList;
|
||||||
@@ -115,11 +114,11 @@ public class IPv6TetheringCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call when upstream NetworkState may be changed.
|
* Call when UpstreamNetworkState may be changed.
|
||||||
* If upstream has ipv6 for tethering, update this new NetworkState
|
* If upstream has ipv6 for tethering, update this new UpstreamNetworkState
|
||||||
* to IpServer. Otherwise stop ipv6 tethering on downstream interfaces.
|
* to IpServer. Otherwise stop ipv6 tethering on downstream interfaces.
|
||||||
*/
|
*/
|
||||||
public void updateUpstreamNetworkState(NetworkState ns) {
|
public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns));
|
Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns));
|
||||||
}
|
}
|
||||||
@@ -144,18 +143,15 @@ public class IPv6TetheringCoordinator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpstreamNetworkState(NetworkState ns) {
|
private void setUpstreamNetworkState(UpstreamNetworkState ns) {
|
||||||
if (ns == null) {
|
if (ns == null) {
|
||||||
mUpstreamNetworkState = null;
|
mUpstreamNetworkState = null;
|
||||||
} else {
|
} else {
|
||||||
// Make a deep copy of the parts we need.
|
// Make a deep copy of the parts we need.
|
||||||
mUpstreamNetworkState = new NetworkState(
|
mUpstreamNetworkState = new UpstreamNetworkState(
|
||||||
null,
|
|
||||||
new LinkProperties(ns.linkProperties),
|
new LinkProperties(ns.linkProperties),
|
||||||
new NetworkCapabilities(ns.networkCapabilities),
|
new NetworkCapabilities(ns.networkCapabilities),
|
||||||
new Network(ns.network),
|
new Network(ns.network));
|
||||||
null,
|
|
||||||
null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mLog.log("setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState));
|
mLog.log("setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState));
|
||||||
@@ -295,14 +291,11 @@ public class IPv6TetheringCoordinator {
|
|||||||
return in6addr;
|
return in6addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toDebugString(NetworkState ns) {
|
private static String toDebugString(UpstreamNetworkState ns) {
|
||||||
if (ns == null) {
|
if (ns == null) {
|
||||||
return "NetworkState{null}";
|
return "UpstreamNetworkState{null}";
|
||||||
}
|
}
|
||||||
return String.format("NetworkState{%s, %s, %s}",
|
return ns.toString();
|
||||||
ns.network,
|
|
||||||
ns.networkCapabilities,
|
|
||||||
ns.linkProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void stopIPv6TetheringOn(IpServer ipServer) {
|
private static void stopIPv6TetheringOn(IpServer ipServer) {
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ import android.net.LinkAddress;
|
|||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
import android.net.TetherStatesParcel;
|
import android.net.TetherStatesParcel;
|
||||||
import android.net.TetheringConfigurationParcel;
|
import android.net.TetheringConfigurationParcel;
|
||||||
@@ -1152,7 +1151,7 @@ public class Tethering {
|
|||||||
|
|
||||||
// Needed because the canonical source of upstream truth is just the
|
// Needed because the canonical source of upstream truth is just the
|
||||||
// upstream interface set, |mCurrentUpstreamIfaceSet|.
|
// upstream interface set, |mCurrentUpstreamIfaceSet|.
|
||||||
private boolean pertainsToCurrentUpstream(NetworkState ns) {
|
private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) {
|
||||||
if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
|
if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
|
||||||
for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
|
for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
|
||||||
if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
|
if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
|
||||||
@@ -1320,7 +1319,7 @@ public class Tethering {
|
|||||||
maybeDunSettingChanged();
|
maybeDunSettingChanged();
|
||||||
|
|
||||||
final TetheringConfiguration config = mConfig;
|
final TetheringConfiguration config = mConfig;
|
||||||
final NetworkState ns = (config.chooseUpstreamAutomatically)
|
final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically)
|
||||||
? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
|
? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
|
||||||
: mUpstreamNetworkMonitor.selectPreferredUpstreamType(
|
: mUpstreamNetworkMonitor.selectPreferredUpstreamType(
|
||||||
config.preferredUpstreamIfaceTypes);
|
config.preferredUpstreamIfaceTypes);
|
||||||
@@ -1341,7 +1340,7 @@ public class Tethering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUpstreamNetwork(NetworkState ns) {
|
protected void setUpstreamNetwork(UpstreamNetworkState ns) {
|
||||||
InterfaceSet ifaces = null;
|
InterfaceSet ifaces = null;
|
||||||
if (ns != null) {
|
if (ns != null) {
|
||||||
// Find the interface with the default IPv4 route. It may be the
|
// Find the interface with the default IPv4 route. It may be the
|
||||||
@@ -1357,7 +1356,7 @@ public class Tethering {
|
|||||||
}
|
}
|
||||||
notifyDownstreamsOfNewUpstreamIface(ifaces);
|
notifyDownstreamsOfNewUpstreamIface(ifaces);
|
||||||
if (ns != null && pertainsToCurrentUpstream(ns)) {
|
if (ns != null && pertainsToCurrentUpstream(ns)) {
|
||||||
// If we already have NetworkState for this network update it immediately.
|
// If we already have UpstreamNetworkState for this network update it immediately.
|
||||||
handleNewUpstreamNetworkState(ns);
|
handleNewUpstreamNetworkState(ns);
|
||||||
} else if (mCurrentUpstreamIfaceSet == null) {
|
} else if (mCurrentUpstreamIfaceSet == null) {
|
||||||
// There are no available upstream networks.
|
// There are no available upstream networks.
|
||||||
@@ -1394,7 +1393,7 @@ public class Tethering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleNewUpstreamNetworkState(NetworkState ns) {
|
protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
|
||||||
mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
|
mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
|
||||||
mOffload.updateUpstreamNetworkState(ns);
|
mOffload.updateUpstreamNetworkState(ns);
|
||||||
}
|
}
|
||||||
@@ -1458,7 +1457,7 @@ public class Tethering {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final NetworkState ns = (NetworkState) o;
|
final UpstreamNetworkState ns = (UpstreamNetworkState) o;
|
||||||
|
|
||||||
if (ns == null || !pertainsToCurrentUpstream(ns)) {
|
if (ns == null || !pertainsToCurrentUpstream(ns)) {
|
||||||
// TODO: In future, this is where upstream evaluation and selection
|
// TODO: In future, this is where upstream evaluation and selection
|
||||||
@@ -1728,7 +1727,7 @@ public class Tethering {
|
|||||||
mOffloadController.stop();
|
mOffloadController.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateUpstreamNetworkState(NetworkState ns) {
|
public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
|
||||||
mOffloadController.setUpstreamLinkProperties(
|
mOffloadController.setUpstreamLinkProperties(
|
||||||
(ns != null) ? ns.linkProperties : null);
|
(ns != null) ? ns.linkProperties : null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.android.server.connectivity.tethering;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.util.InterfaceSet;
|
import android.net.util.InterfaceSet;
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ public final class TetheringInterfaceUtils {
|
|||||||
* Get upstream interfaces for tethering based on default routes for IPv4/IPv6.
|
* Get upstream interfaces for tethering based on default routes for IPv4/IPv6.
|
||||||
* @return null if there is no usable interface, or a set of at least one interface otherwise.
|
* @return null if there is no usable interface, or a set of at least one interface otherwise.
|
||||||
*/
|
*/
|
||||||
public static @Nullable InterfaceSet getTetheringInterfaces(NetworkState ns) {
|
public static @Nullable InterfaceSet getTetheringInterfaces(UpstreamNetworkState ns) {
|
||||||
if (ns == null) {
|
if (ns == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -51,7 +50,7 @@ public final class TetheringInterfaceUtils {
|
|||||||
* Get the upstream interface for IPv6 tethering.
|
* Get the upstream interface for IPv6 tethering.
|
||||||
* @return null if there is no usable interface, or the interface name otherwise.
|
* @return null if there is no usable interface, or the interface name otherwise.
|
||||||
*/
|
*/
|
||||||
public static @Nullable String getIPv6Interface(NetworkState ns) {
|
public static @Nullable String getIPv6Interface(UpstreamNetworkState ns) {
|
||||||
// Broadly speaking:
|
// Broadly speaking:
|
||||||
//
|
//
|
||||||
// [1] does the upstream have an IPv6 default route?
|
// [1] does the upstream have an IPv6 default route?
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import android.net.LinkProperties;
|
|||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.util.PrefixUtils;
|
import android.net.util.PrefixUtils;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -90,7 +89,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
private final StateMachine mTarget;
|
private final StateMachine mTarget;
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private final int mWhat;
|
private final int mWhat;
|
||||||
private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
|
private final HashMap<Network, UpstreamNetworkState> mNetworkMap = new HashMap<>();
|
||||||
private HashSet<IpPrefix> mLocalPrefixes;
|
private HashSet<IpPrefix> mLocalPrefixes;
|
||||||
private ConnectivityManager mCM;
|
private ConnectivityManager mCM;
|
||||||
private EntitlementManager mEntitlementMgr;
|
private EntitlementManager mEntitlementMgr;
|
||||||
@@ -236,7 +235,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
/**
|
/**
|
||||||
* Select the first available network from |perferredTypes|.
|
* Select the first available network from |perferredTypes|.
|
||||||
*/
|
*/
|
||||||
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
|
public UpstreamNetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
|
||||||
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
|
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
|
||||||
mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
|
mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
|
||||||
|
|
||||||
@@ -274,8 +273,8 @@ public class UpstreamNetworkMonitor {
|
|||||||
* preferred upstream would be DUN otherwise preferred upstream is the same as default network.
|
* preferred upstream would be DUN otherwise preferred upstream is the same as default network.
|
||||||
* Returns null if no current upstream is available.
|
* Returns null if no current upstream is available.
|
||||||
*/
|
*/
|
||||||
public NetworkState getCurrentPreferredUpstream() {
|
public UpstreamNetworkState getCurrentPreferredUpstream() {
|
||||||
final NetworkState dfltState = (mDefaultInternetNetwork != null)
|
final UpstreamNetworkState dfltState = (mDefaultInternetNetwork != null)
|
||||||
? mNetworkMap.get(mDefaultInternetNetwork)
|
? mNetworkMap.get(mDefaultInternetNetwork)
|
||||||
: null;
|
: null;
|
||||||
if (isNetworkUsableAndNotCellular(dfltState)) return dfltState;
|
if (isNetworkUsableAndNotCellular(dfltState)) return dfltState;
|
||||||
@@ -312,11 +311,11 @@ public class UpstreamNetworkMonitor {
|
|||||||
if (mNetworkMap.containsKey(network)) return;
|
if (mNetworkMap.containsKey(network)) return;
|
||||||
|
|
||||||
if (VDBG) Log.d(TAG, "onAvailable for " + network);
|
if (VDBG) Log.d(TAG, "onAvailable for " + network);
|
||||||
mNetworkMap.put(network, new NetworkState(null, null, null, network, null, null));
|
mNetworkMap.put(network, new UpstreamNetworkState(null, null, network));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNetCap(Network network, NetworkCapabilities newNc) {
|
private void handleNetCap(Network network, NetworkCapabilities newNc) {
|
||||||
final NetworkState prev = mNetworkMap.get(network);
|
final UpstreamNetworkState prev = mNetworkMap.get(network);
|
||||||
if (prev == null || newNc.equals(prev.networkCapabilities)) {
|
if (prev == null || newNc.equals(prev.networkCapabilities)) {
|
||||||
// Ignore notifications about networks for which we have not yet
|
// Ignore notifications about networks for which we have not yet
|
||||||
// received onAvailable() (should never happen) and any duplicate
|
// received onAvailable() (should never happen) and any duplicate
|
||||||
@@ -336,15 +335,15 @@ public class UpstreamNetworkMonitor {
|
|||||||
mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal);
|
mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNetworkMap.put(network, new NetworkState(
|
mNetworkMap.put(network, new UpstreamNetworkState(
|
||||||
null, prev.linkProperties, newNc, network, null, null));
|
prev.linkProperties, newNc, network));
|
||||||
// TODO: If sufficient information is available to select a more
|
// TODO: If sufficient information is available to select a more
|
||||||
// preferable upstream, do so now and notify the target.
|
// preferable upstream, do so now and notify the target.
|
||||||
notifyTarget(EVENT_ON_CAPABILITIES, network);
|
notifyTarget(EVENT_ON_CAPABILITIES, network);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLinkProp(Network network, LinkProperties newLp) {
|
private void handleLinkProp(Network network, LinkProperties newLp) {
|
||||||
final NetworkState prev = mNetworkMap.get(network);
|
final UpstreamNetworkState prev = mNetworkMap.get(network);
|
||||||
if (prev == null || newLp.equals(prev.linkProperties)) {
|
if (prev == null || newLp.equals(prev.linkProperties)) {
|
||||||
// Ignore notifications about networks for which we have not yet
|
// Ignore notifications about networks for which we have not yet
|
||||||
// received onAvailable() (should never happen) and any duplicate
|
// received onAvailable() (should never happen) and any duplicate
|
||||||
@@ -357,8 +356,8 @@ public class UpstreamNetworkMonitor {
|
|||||||
network, newLp));
|
network, newLp));
|
||||||
}
|
}
|
||||||
|
|
||||||
mNetworkMap.put(network, new NetworkState(
|
mNetworkMap.put(network, new UpstreamNetworkState(
|
||||||
null, newLp, prev.networkCapabilities, network, null, null));
|
newLp, prev.networkCapabilities, network));
|
||||||
// TODO: If sufficient information is available to select a more
|
// TODO: If sufficient information is available to select a more
|
||||||
// preferable upstream, do so now and notify the target.
|
// preferable upstream, do so now and notify the target.
|
||||||
notifyTarget(EVENT_ON_LINKPROPERTIES, network);
|
notifyTarget(EVENT_ON_LINKPROPERTIES, network);
|
||||||
@@ -509,11 +508,11 @@ public class UpstreamNetworkMonitor {
|
|||||||
|
|
||||||
private static class TypeStatePair {
|
private static class TypeStatePair {
|
||||||
public int type = TYPE_NONE;
|
public int type = TYPE_NONE;
|
||||||
public NetworkState ns = null;
|
public UpstreamNetworkState ns = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TypeStatePair findFirstAvailableUpstreamByType(
|
private static TypeStatePair findFirstAvailableUpstreamByType(
|
||||||
Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes,
|
Iterable<UpstreamNetworkState> netStates, Iterable<Integer> preferredTypes,
|
||||||
boolean isCellularUpstreamPermitted) {
|
boolean isCellularUpstreamPermitted) {
|
||||||
final TypeStatePair result = new TypeStatePair();
|
final TypeStatePair result = new TypeStatePair();
|
||||||
|
|
||||||
@@ -532,7 +531,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
|
|
||||||
nc.setSingleUid(Process.myUid());
|
nc.setSingleUid(Process.myUid());
|
||||||
|
|
||||||
for (NetworkState value : netStates) {
|
for (UpstreamNetworkState value : netStates) {
|
||||||
if (!nc.satisfiedByNetworkCapabilities(value.networkCapabilities)) {
|
if (!nc.satisfiedByNetworkCapabilities(value.networkCapabilities)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -546,10 +545,10 @@ public class UpstreamNetworkMonitor {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HashSet<IpPrefix> allLocalPrefixes(Iterable<NetworkState> netStates) {
|
private static HashSet<IpPrefix> allLocalPrefixes(Iterable<UpstreamNetworkState> netStates) {
|
||||||
final HashSet<IpPrefix> prefixSet = new HashSet<>();
|
final HashSet<IpPrefix> prefixSet = new HashSet<>();
|
||||||
|
|
||||||
for (NetworkState ns : netStates) {
|
for (UpstreamNetworkState ns : netStates) {
|
||||||
final LinkProperties lp = ns.linkProperties;
|
final LinkProperties lp = ns.linkProperties;
|
||||||
if (lp == null) continue;
|
if (lp == null) continue;
|
||||||
prefixSet.addAll(PrefixUtils.localPrefixesFrom(lp));
|
prefixSet.addAll(PrefixUtils.localPrefixesFrom(lp));
|
||||||
@@ -563,7 +562,7 @@ public class UpstreamNetworkMonitor {
|
|||||||
return Integer.toString(nc.getSignalStrength());
|
return Integer.toString(nc.getSignalStrength());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isCellular(NetworkState ns) {
|
private static boolean isCellular(UpstreamNetworkState ns) {
|
||||||
return (ns != null) && isCellular(ns.networkCapabilities);
|
return (ns != null) && isCellular(ns.networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,18 +571,19 @@ public class UpstreamNetworkMonitor {
|
|||||||
&& nc.hasCapability(NET_CAPABILITY_NOT_VPN);
|
&& nc.hasCapability(NET_CAPABILITY_NOT_VPN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasCapability(NetworkState ns, int netCap) {
|
private static boolean hasCapability(UpstreamNetworkState ns, int netCap) {
|
||||||
return (ns != null) && (ns.networkCapabilities != null)
|
return (ns != null) && (ns.networkCapabilities != null)
|
||||||
&& ns.networkCapabilities.hasCapability(netCap);
|
&& ns.networkCapabilities.hasCapability(netCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNetworkUsableAndNotCellular(NetworkState ns) {
|
private static boolean isNetworkUsableAndNotCellular(UpstreamNetworkState ns) {
|
||||||
return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
|
return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
|
||||||
&& !isCellular(ns.networkCapabilities);
|
&& !isCellular(ns.networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState findFirstDunNetwork(Iterable<NetworkState> netStates) {
|
private static UpstreamNetworkState findFirstDunNetwork(
|
||||||
for (NetworkState ns : netStates) {
|
Iterable<UpstreamNetworkState> netStates) {
|
||||||
|
for (UpstreamNetworkState ns : netStates) {
|
||||||
if (isCellular(ns) && hasCapability(ns, NET_CAPABILITY_DUN)) return ns;
|
if (isCellular(ns) && hasCapability(ns, NET_CAPABILITY_DUN)) return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.server.connectivity.tethering;
|
||||||
|
|
||||||
|
import android.net.LinkProperties;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Snapshot of tethering upstream network state.
|
||||||
|
*/
|
||||||
|
public class UpstreamNetworkState {
|
||||||
|
/** {@link LinkProperties}. */
|
||||||
|
public final LinkProperties linkProperties;
|
||||||
|
/** {@link NetworkCapabilities}. */
|
||||||
|
public final NetworkCapabilities networkCapabilities;
|
||||||
|
/** {@link Network}. */
|
||||||
|
public final Network network;
|
||||||
|
|
||||||
|
/** Constructs a new UpstreamNetworkState. */
|
||||||
|
public UpstreamNetworkState(LinkProperties linkProperties,
|
||||||
|
NetworkCapabilities networkCapabilities, Network network) {
|
||||||
|
this.linkProperties = linkProperties;
|
||||||
|
this.networkCapabilities = networkCapabilities;
|
||||||
|
this.network = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("UpstreamNetworkState{%s, %s, %s}",
|
||||||
|
network == null ? "null" : network,
|
||||||
|
networkCapabilities == null ? "null" : networkCapabilities,
|
||||||
|
linkProperties == null ? "null" : linkProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,6 @@ import static android.net.ConnectivityManager.TETHERING_USB;
|
|||||||
import static android.net.ConnectivityManager.TETHERING_WIFI;
|
import static android.net.ConnectivityManager.TETHERING_WIFI;
|
||||||
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
|
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
|
||||||
import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
|
import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
|
||||||
import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
|
import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
|
||||||
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
|
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
|
||||||
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
|
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
|
||||||
@@ -82,7 +81,6 @@ import android.net.Network;
|
|||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.TetherStatesParcel;
|
import android.net.TetherStatesParcel;
|
||||||
@@ -360,10 +358,8 @@ public class TetheringTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
|
private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
|
||||||
boolean with464xlat) {
|
boolean withIPv6, boolean with464xlat) {
|
||||||
final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, 0, null, null);
|
|
||||||
info.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
|
|
||||||
final LinkProperties prop = new LinkProperties();
|
final LinkProperties prop = new LinkProperties();
|
||||||
prop.setInterfaceName(TEST_MOBILE_IFNAME);
|
prop.setInterfaceName(TEST_MOBILE_IFNAME);
|
||||||
|
|
||||||
@@ -393,22 +389,22 @@ public class TetheringTest {
|
|||||||
|
|
||||||
final NetworkCapabilities capabilities = new NetworkCapabilities()
|
final NetworkCapabilities capabilities = new NetworkCapabilities()
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
||||||
return new NetworkState(info, prop, capabilities, new Network(100), null, "netid");
|
return new UpstreamNetworkState(prop, capabilities, new Network(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState buildMobileIPv4UpstreamState() {
|
private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
|
||||||
return buildMobileUpstreamState(true, false, false);
|
return buildMobileUpstreamState(true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState buildMobileIPv6UpstreamState() {
|
private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
|
||||||
return buildMobileUpstreamState(false, true, false);
|
return buildMobileUpstreamState(false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState buildMobileDualStackUpstreamState() {
|
private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
|
||||||
return buildMobileUpstreamState(true, true, false);
|
return buildMobileUpstreamState(true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkState buildMobile464xlatUpstreamState() {
|
private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
|
||||||
return buildMobileUpstreamState(false, true, true);
|
return buildMobileUpstreamState(false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,7 +558,7 @@ public class TetheringTest {
|
|||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareUsbTethering(NetworkState upstreamState) {
|
private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
|
||||||
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
|
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
|
||||||
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
|
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
|
||||||
.thenReturn(upstreamState);
|
.thenReturn(upstreamState);
|
||||||
@@ -577,7 +573,7 @@ public class TetheringTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
|
public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
|
||||||
NetworkState upstreamState = buildMobileIPv4UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
|
||||||
prepareUsbTethering(upstreamState);
|
prepareUsbTethering(upstreamState);
|
||||||
|
|
||||||
// This should produce no activity of any kind.
|
// This should produce no activity of any kind.
|
||||||
@@ -657,14 +653,14 @@ public class TetheringTest {
|
|||||||
/**
|
/**
|
||||||
* Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
|
* Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
|
||||||
*/
|
*/
|
||||||
private void sendIPv6TetherUpdates(NetworkState upstreamState) {
|
private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
|
||||||
// IPv6TetheringCoordinator must have been notified of downstream
|
// IPv6TetheringCoordinator must have been notified of downstream
|
||||||
verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
|
verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
|
||||||
argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
|
argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
|
||||||
eq(IpServer.STATE_TETHERED));
|
eq(IpServer.STATE_TETHERED));
|
||||||
|
|
||||||
for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
|
for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
|
||||||
NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
|
UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
|
||||||
ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
|
ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
|
||||||
upstreamState.linkProperties.isIpv6Provisioned()
|
upstreamState.linkProperties.isIpv6Provisioned()
|
||||||
? ipv6OnlyState.linkProperties
|
? ipv6OnlyState.linkProperties
|
||||||
@@ -673,7 +669,7 @@ public class TetheringTest {
|
|||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runUsbTethering(NetworkState upstreamState) {
|
private void runUsbTethering(UpstreamNetworkState upstreamState) {
|
||||||
prepareUsbTethering(upstreamState);
|
prepareUsbTethering(upstreamState);
|
||||||
sendUsbBroadcast(true, true, true);
|
sendUsbBroadcast(true, true, true);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
@@ -681,7 +677,7 @@ public class TetheringTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void workingMobileUsbTethering_IPv4() throws Exception {
|
public void workingMobileUsbTethering_IPv4() throws Exception {
|
||||||
NetworkState upstreamState = buildMobileIPv4UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
@@ -696,7 +692,7 @@ public class TetheringTest {
|
|||||||
public void workingMobileUsbTethering_IPv4LegacyDhcp() {
|
public void workingMobileUsbTethering_IPv4LegacyDhcp() {
|
||||||
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
|
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
|
||||||
sendConfigurationChanged();
|
sendConfigurationChanged();
|
||||||
final NetworkState upstreamState = buildMobileIPv4UpstreamState();
|
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
sendIPv6TetherUpdates(upstreamState);
|
sendIPv6TetherUpdates(upstreamState);
|
||||||
|
|
||||||
@@ -705,7 +701,7 @@ public class TetheringTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void workingMobileUsbTethering_IPv6() throws Exception {
|
public void workingMobileUsbTethering_IPv6() throws Exception {
|
||||||
NetworkState upstreamState = buildMobileIPv6UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
@@ -718,7 +714,7 @@ public class TetheringTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void workingMobileUsbTethering_DualStack() throws Exception {
|
public void workingMobileUsbTethering_DualStack() throws Exception {
|
||||||
NetworkState upstreamState = buildMobileDualStackUpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
@@ -733,7 +729,7 @@ public class TetheringTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
|
public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
|
||||||
NetworkState upstreamState = buildMobile464xlatUpstreamState();
|
UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
||||||
@@ -751,7 +747,7 @@ public class TetheringTest {
|
|||||||
@Test
|
@Test
|
||||||
public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
|
public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
|
||||||
// Setup IPv6
|
// Setup IPv6
|
||||||
NetworkState upstreamState = buildMobileIPv6UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
@@ -789,7 +785,7 @@ public class TetheringTest {
|
|||||||
sendConfigurationChanged();
|
sendConfigurationChanged();
|
||||||
|
|
||||||
// Setup IPv6
|
// Setup IPv6
|
||||||
final NetworkState upstreamState = buildMobileIPv6UpstreamState();
|
final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
// UpstreamNetworkMonitor should choose upstream automatically
|
// UpstreamNetworkMonitor should choose upstream automatically
|
||||||
@@ -1172,7 +1168,7 @@ public class TetheringTest {
|
|||||||
TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
|
TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
|
||||||
assertEquals(tetherState, null);
|
assertEquals(tetherState, null);
|
||||||
// 2. Enable wifi tethering.
|
// 2. Enable wifi tethering.
|
||||||
NetworkState upstreamState = buildMobileDualStackUpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
|
||||||
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
|
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
|
||||||
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
|
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
|
||||||
.thenReturn(upstreamState);
|
.thenReturn(upstreamState);
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import android.net.LinkProperties;
|
|||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkState;
|
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@@ -539,7 +538,7 @@ public class UpstreamNetworkMonitorTest {
|
|||||||
mUNM.selectPreferredUpstreamType(preferredTypes));
|
mUNM.selectPreferredUpstreamType(preferredTypes));
|
||||||
verify(mEntitleMgr, times(1)).maybeRunProvisioning();
|
verify(mEntitleMgr, times(1)).maybeRunProvisioning();
|
||||||
}
|
}
|
||||||
private void assertSatisfiesLegacyType(int legacyType, NetworkState ns) {
|
private void assertSatisfiesLegacyType(int legacyType, UpstreamNetworkState ns) {
|
||||||
if (legacyType == TYPE_NONE) {
|
if (legacyType == TYPE_NONE) {
|
||||||
assertTrue(ns == null);
|
assertTrue(ns == null);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user