[Tether09] Use INetd to call netd directly
- Using INetd to communicate with netd directly instead of using
NetworkManagementService which is a wrapper of INetd and don't have plan
to be updatable.
- Also replace InterfaceConfiguration by InterfaceController.
- Remove redundant interface flags. Only set interface up/down flag to
netd because netd only use these two flags for INetd#interfaceSetCfg.
- Note that tethering still use NetworkManagementService
to register tethering stats provider and it would also be replaced with
other way in follow up change.
Bug: 136040414
Test: -build, flash, boot
-atest TetheringTests
Change-Id: I4ab0ad387d4bd1773ff94d3b380c1720df07f8d5
This commit is contained in:
@@ -20,7 +20,7 @@ java_defaults {
|
|||||||
srcs: [
|
srcs: [
|
||||||
"src/**/*.java",
|
"src/**/*.java",
|
||||||
":framework-tethering-shared-srcs",
|
":framework-tethering-shared-srcs",
|
||||||
":net-module-utils-srcs",
|
":tethering-module-utils-srcs",
|
||||||
":services-tethering-shared-srcs",
|
":services-tethering-shared-srcs",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.INetd;
|
import android.net.INetd;
|
||||||
import android.net.INetworkStackStatusCallback;
|
import android.net.INetworkStackStatusCallback;
|
||||||
import android.net.INetworkStatsService;
|
import android.net.INetworkStatsService;
|
||||||
import android.net.InterfaceConfiguration;
|
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -38,11 +37,11 @@ import android.net.dhcp.DhcpServingParamsParcel;
|
|||||||
import android.net.dhcp.DhcpServingParamsParcelExt;
|
import android.net.dhcp.DhcpServingParamsParcelExt;
|
||||||
import android.net.dhcp.IDhcpServer;
|
import android.net.dhcp.IDhcpServer;
|
||||||
import android.net.ip.RouterAdvertisementDaemon.RaParams;
|
import android.net.ip.RouterAdvertisementDaemon.RaParams;
|
||||||
|
import android.net.shared.NetdUtils;
|
||||||
|
import android.net.shared.RouteUtils;
|
||||||
import android.net.util.InterfaceParams;
|
import android.net.util.InterfaceParams;
|
||||||
import android.net.util.InterfaceSet;
|
import android.net.util.InterfaceSet;
|
||||||
import android.net.util.NetdService;
|
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.INetworkManagementService;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -144,10 +143,6 @@ public class IpServer extends StateMachine {
|
|||||||
return InterfaceParams.getByName(ifName);
|
return InterfaceParams.getByName(ifName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public INetd getNetdService() {
|
|
||||||
return NetdService.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a DhcpServer instance to be used by IpServer. */
|
/** Create a DhcpServer instance to be used by IpServer. */
|
||||||
public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
|
public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
|
||||||
DhcpServerCallbacks cb);
|
DhcpServerCallbacks cb);
|
||||||
@@ -180,7 +175,6 @@ public class IpServer extends StateMachine {
|
|||||||
private final State mUnavailableState;
|
private final State mUnavailableState;
|
||||||
|
|
||||||
private final SharedLog mLog;
|
private final SharedLog mLog;
|
||||||
private final INetworkManagementService mNMService;
|
|
||||||
private final INetd mNetd;
|
private final INetd mNetd;
|
||||||
private final INetworkStatsService mStatsService;
|
private final INetworkStatsService mStatsService;
|
||||||
private final Callback mCallback;
|
private final Callback mCallback;
|
||||||
@@ -210,15 +204,15 @@ public class IpServer extends StateMachine {
|
|||||||
private int mDhcpServerStartIndex = 0;
|
private int mDhcpServerStartIndex = 0;
|
||||||
private IDhcpServer mDhcpServer;
|
private IDhcpServer mDhcpServer;
|
||||||
private RaParams mLastRaParams;
|
private RaParams mLastRaParams;
|
||||||
|
private LinkAddress mIpv4Address;
|
||||||
|
|
||||||
public IpServer(
|
public IpServer(
|
||||||
String ifaceName, Looper looper, int interfaceType, SharedLog log,
|
String ifaceName, Looper looper, int interfaceType, SharedLog log,
|
||||||
INetworkManagementService nMService, INetworkStatsService statsService,
|
INetd netd, INetworkStatsService statsService, Callback callback,
|
||||||
Callback callback, boolean usingLegacyDhcp, Dependencies deps) {
|
boolean usingLegacyDhcp, Dependencies deps) {
|
||||||
super(ifaceName, looper);
|
super(ifaceName, looper);
|
||||||
mLog = log.forSubComponent(ifaceName);
|
mLog = log.forSubComponent(ifaceName);
|
||||||
mNMService = nMService;
|
mNetd = netd;
|
||||||
mNetd = deps.getNetdService();
|
|
||||||
mStatsService = statsService;
|
mStatsService = statsService;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
|
mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog);
|
||||||
@@ -347,7 +341,7 @@ public class IpServer extends StateMachine {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
e.rethrowFromSystemServer();
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -395,7 +389,8 @@ public class IpServer extends StateMachine {
|
|||||||
});
|
});
|
||||||
mDhcpServer = null;
|
mDhcpServer = null;
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
e.rethrowFromSystemServer();
|
mLog.e("Error stopping DHCP", e);
|
||||||
|
// Not much more we can do here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,85 +409,69 @@ public class IpServer extends StateMachine {
|
|||||||
// NOTE: All of configureIPv4() will be refactored out of existence
|
// NOTE: All of configureIPv4() will be refactored out of existence
|
||||||
// into calls to InterfaceController, shared with startIPv4().
|
// into calls to InterfaceController, shared with startIPv4().
|
||||||
mInterfaceCtrl.clearIPv4Address();
|
mInterfaceCtrl.clearIPv4Address();
|
||||||
|
mIpv4Address = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this in terms of calls to InterfaceController.
|
|
||||||
private boolean configureIPv4(boolean enabled) {
|
private boolean configureIPv4(boolean enabled) {
|
||||||
if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
|
if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
|
||||||
|
|
||||||
// TODO: Replace this hard-coded information with dynamically selected
|
// TODO: Replace this hard-coded information with dynamically selected
|
||||||
// config passed down to us by a higher layer IP-coordinating element.
|
// config passed down to us by a higher layer IP-coordinating element.
|
||||||
String ipAsString = null;
|
final Inet4Address srvAddr;
|
||||||
int prefixLen = 0;
|
int prefixLen = 0;
|
||||||
|
try {
|
||||||
if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
|
if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
|
||||||
ipAsString = USB_NEAR_IFACE_ADDR;
|
srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR);
|
||||||
prefixLen = USB_PREFIX_LENGTH;
|
prefixLen = USB_PREFIX_LENGTH;
|
||||||
} else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
|
} else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
|
||||||
ipAsString = getRandomWifiIPv4Address();
|
srvAddr = (Inet4Address) parseNumericAddress(getRandomWifiIPv4Address());
|
||||||
prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
|
prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
|
||||||
} else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI_P2P) {
|
} else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI_P2P) {
|
||||||
ipAsString = WIFI_P2P_IFACE_ADDR;
|
srvAddr = (Inet4Address) parseNumericAddress(WIFI_P2P_IFACE_ADDR);
|
||||||
prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH;
|
prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH;
|
||||||
} else {
|
} else {
|
||||||
// BT configures the interface elsewhere: only start DHCP.
|
// BT configures the interface elsewhere: only start DHCP.
|
||||||
final Inet4Address srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
|
// TODO: make all tethering types behave the same way, and delete the bluetooth
|
||||||
|
// code that calls into NetworkManagementService directly.
|
||||||
|
srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
|
||||||
|
mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
|
||||||
return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
|
return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
|
||||||
}
|
}
|
||||||
|
mIpv4Address = new LinkAddress(srvAddr, prefixLen);
|
||||||
final LinkAddress linkAddr;
|
} catch (IllegalArgumentException e) {
|
||||||
try {
|
mLog.e("Error selecting ipv4 address", e);
|
||||||
final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName);
|
if (!enabled) stopDhcp();
|
||||||
if (ifcg == null) {
|
|
||||||
mLog.e("Received null interface config");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
InetAddress addr = parseNumericAddress(ipAsString);
|
final Boolean setIfaceUp;
|
||||||
linkAddr = new LinkAddress(addr, prefixLen);
|
|
||||||
ifcg.setLinkAddress(linkAddr);
|
|
||||||
if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
|
if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
|
||||||
// The WiFi stack has ownership of the interface up/down state.
|
// The WiFi stack has ownership of the interface up/down state.
|
||||||
// It is unclear whether the Bluetooth or USB stacks will manage their own
|
// It is unclear whether the Bluetooth or USB stacks will manage their own
|
||||||
// state.
|
// state.
|
||||||
ifcg.ignoreInterfaceUpDownStatus();
|
setIfaceUp = null;
|
||||||
} else {
|
} else {
|
||||||
if (enabled) {
|
setIfaceUp = enabled;
|
||||||
ifcg.setInterfaceUp();
|
|
||||||
} else {
|
|
||||||
ifcg.setInterfaceDown();
|
|
||||||
}
|
}
|
||||||
}
|
if (!mInterfaceCtrl.setInterfaceConfiguration(mIpv4Address, setIfaceUp)) {
|
||||||
ifcg.clearFlag("running");
|
mLog.e("Error configuring interface");
|
||||||
|
if (!enabled) stopDhcp();
|
||||||
// TODO: this may throw if the interface is already gone. Do proper handling and
|
|
||||||
// simplify the DHCP server start/stop.
|
|
||||||
mNMService.setInterfaceConfig(mIfaceName, ifcg);
|
|
||||||
|
|
||||||
if (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
mLog.e("Error configuring interface " + e);
|
if (!configureDhcp(enabled, srvAddr, prefixLen)) {
|
||||||
if (!enabled) {
|
|
||||||
try {
|
|
||||||
// Calling stopDhcp several times is fine
|
|
||||||
stopDhcp();
|
|
||||||
} catch (Exception dhcpError) {
|
|
||||||
mLog.e("Error stopping DHCP", dhcpError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly-connected route.
|
// Directly-connected route.
|
||||||
final IpPrefix ipv4Prefix = new IpPrefix(linkAddr.getAddress(),
|
final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
|
||||||
linkAddr.getPrefixLength());
|
mIpv4Address.getPrefixLength());
|
||||||
final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST);
|
final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
mLinkProperties.addLinkAddress(linkAddr);
|
mLinkProperties.addLinkAddress(mIpv4Address);
|
||||||
mLinkProperties.addRoute(route);
|
mLinkProperties.addRoute(route);
|
||||||
} else {
|
} else {
|
||||||
mLinkProperties.removeLinkAddress(linkAddr);
|
mLinkProperties.removeLinkAddress(mIpv4Address);
|
||||||
mLinkProperties.removeRoute(route);
|
mLinkProperties.removeRoute(route);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -584,15 +563,13 @@ public class IpServer extends StateMachine {
|
|||||||
if (!deprecatedPrefixes.isEmpty()) {
|
if (!deprecatedPrefixes.isEmpty()) {
|
||||||
final ArrayList<RouteInfo> toBeRemoved =
|
final ArrayList<RouteInfo> toBeRemoved =
|
||||||
getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
|
getLocalRoutesFor(mIfaceName, deprecatedPrefixes);
|
||||||
try {
|
// Remove routes from local network.
|
||||||
final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved);
|
final int removalFailures = RouteUtils.removeRoutesFromLocalNetwork(
|
||||||
|
mNetd, toBeRemoved);
|
||||||
if (removalFailures > 0) {
|
if (removalFailures > 0) {
|
||||||
mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
|
mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
|
||||||
removalFailures));
|
removalFailures));
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
|
||||||
mLog.e("Failed to remove IPv6 routes from local table: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
|
for (RouteInfo route : toBeRemoved) mLinkProperties.removeRoute(route);
|
||||||
}
|
}
|
||||||
@@ -608,14 +585,19 @@ public class IpServer extends StateMachine {
|
|||||||
final ArrayList<RouteInfo> toBeAdded =
|
final ArrayList<RouteInfo> toBeAdded =
|
||||||
getLocalRoutesFor(mIfaceName, addedPrefixes);
|
getLocalRoutesFor(mIfaceName, addedPrefixes);
|
||||||
try {
|
try {
|
||||||
// It's safe to call addInterfaceToLocalNetwork() even if
|
// It's safe to call networkAddInterface() even if
|
||||||
// the interface is already in the local_network. Note also
|
// the interface is already in the local_network.
|
||||||
// that adding routes that already exist does not cause an
|
mNetd.networkAddInterface(INetd.LOCAL_NET_ID, mIfaceName);
|
||||||
// error (EEXIST is silently ignored).
|
try {
|
||||||
mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded);
|
// Add routes from local network. Note that adding routes that
|
||||||
} catch (Exception e) {
|
// already exist does not cause an error (EEXIST is silently ignored).
|
||||||
|
RouteUtils.addRoutesToLocalNetwork(mNetd, mIfaceName, toBeAdded);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
mLog.e("Failed to add IPv6 routes to local table: " + e);
|
mLog.e("Failed to add IPv6 routes to local table: " + e);
|
||||||
}
|
}
|
||||||
|
} catch (ServiceSpecificException | RemoteException e) {
|
||||||
|
mLog.e("Failed to add " + mIfaceName + " to local table: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
|
for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route);
|
||||||
}
|
}
|
||||||
@@ -762,8 +744,10 @@ public class IpServer extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mNMService.tetherInterface(mIfaceName);
|
final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
|
||||||
} catch (Exception e) {
|
mIpv4Address.getPrefixLength());
|
||||||
|
NetdUtils.tetherInterface(mNetd, mIfaceName, ipv4Prefix);
|
||||||
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLog.e("Error Tethering: " + e);
|
mLog.e("Error Tethering: " + e);
|
||||||
mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
||||||
return;
|
return;
|
||||||
@@ -784,8 +768,8 @@ public class IpServer extends StateMachine {
|
|||||||
stopIPv6();
|
stopIPv6();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mNMService.untetherInterface(mIfaceName);
|
NetdUtils.untetherInterface(mNetd, mIfaceName);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
|
mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
|
||||||
mLog.e("Failed to untether interface: " + e);
|
mLog.e("Failed to untether interface: " + e);
|
||||||
}
|
}
|
||||||
@@ -901,17 +885,17 @@ public class IpServer extends StateMachine {
|
|||||||
// About to tear down NAT; gather remaining statistics.
|
// About to tear down NAT; gather remaining statistics.
|
||||||
mStatsService.forceUpdate();
|
mStatsService.forceUpdate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (VDBG) Log.e(TAG, "Exception in forceUpdate: " + e.toString());
|
mLog.e("Exception in forceUpdate: " + e.toString());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mNMService.stopInterfaceForwarding(mIfaceName, upstreamIface);
|
mNetd.ipfwdRemoveInterfaceForward(mIfaceName, upstreamIface);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
if (VDBG) Log.e(TAG, "Exception in removeInterfaceForward: " + e.toString());
|
mLog.e("Exception in ipfwdRemoveInterfaceForward: " + e.toString());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mNMService.disableNat(mIfaceName, upstreamIface);
|
mNetd.tetherRemoveForward(mIfaceName, upstreamIface);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
if (VDBG) Log.e(TAG, "Exception in disableNat: " + e.toString());
|
mLog.e("Exception in disableNat: " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,10 +931,10 @@ public class IpServer extends StateMachine {
|
|||||||
|
|
||||||
for (String ifname : added) {
|
for (String ifname : added) {
|
||||||
try {
|
try {
|
||||||
mNMService.enableNat(mIfaceName, ifname);
|
mNetd.tetherAddForward(mIfaceName, ifname);
|
||||||
mNMService.startInterfaceForwarding(mIfaceName, ifname);
|
mNetd.ipfwdAddInterfaceForward(mIfaceName, ifname);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLog.e("Exception enabling NAT: " + e);
|
mLog.e("Exception enabling NAT: " + e.toString());
|
||||||
cleanupUpstream();
|
cleanupUpstream();
|
||||||
mLastError = ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
|
mLastError = ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
|
||||||
transitionTo(mInitialState);
|
transitionTo(mInitialState);
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ import android.net.NetworkUtils;
|
|||||||
import android.net.TetherStatesParcel;
|
import android.net.TetherStatesParcel;
|
||||||
import android.net.TetheringConfigurationParcel;
|
import android.net.TetheringConfigurationParcel;
|
||||||
import android.net.ip.IpServer;
|
import android.net.ip.IpServer;
|
||||||
|
import android.net.shared.NetdUtils;
|
||||||
import android.net.util.BaseNetdUnsolicitedEventListener;
|
import android.net.util.BaseNetdUnsolicitedEventListener;
|
||||||
import android.net.util.InterfaceSet;
|
import android.net.util.InterfaceSet;
|
||||||
import android.net.util.PrefixUtils;
|
import android.net.util.PrefixUtils;
|
||||||
@@ -87,12 +88,12 @@ import android.net.wifi.p2p.WifiP2pManager;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.INetworkManagementService;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteCallbackList;
|
import android.os.RemoteCallbackList;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
|
import android.os.ServiceSpecificException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.telephony.PhoneStateListener;
|
import android.telephony.PhoneStateListener;
|
||||||
@@ -102,6 +103,9 @@ import android.util.ArrayMap;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||||
import com.android.internal.notification.SystemNotificationChannels;
|
import com.android.internal.notification.SystemNotificationChannels;
|
||||||
@@ -139,6 +143,8 @@ public class Tethering {
|
|||||||
};
|
};
|
||||||
private static final SparseArray<String> sMagicDecoderRing =
|
private static final SparseArray<String> sMagicDecoderRing =
|
||||||
MessageUtils.findMessageNames(sMessageClasses);
|
MessageUtils.findMessageNames(sMessageClasses);
|
||||||
|
// Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
|
||||||
|
private static final int NETID_UNSET = 0;
|
||||||
|
|
||||||
private static class TetherState {
|
private static class TetherState {
|
||||||
public final IpServer ipServer;
|
public final IpServer ipServer;
|
||||||
@@ -172,8 +178,6 @@ public class Tethering {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ArrayMap<String, TetherState> mTetherStates;
|
private final ArrayMap<String, TetherState> mTetherStates;
|
||||||
private final BroadcastReceiver mStateReceiver;
|
private final BroadcastReceiver mStateReceiver;
|
||||||
// Stopship: replace mNMService before production.
|
|
||||||
private final INetworkManagementService mNMService;
|
|
||||||
private final INetworkStatsService mStatsService;
|
private final INetworkStatsService mStatsService;
|
||||||
private final INetworkPolicyManager mPolicyManager;
|
private final INetworkPolicyManager mPolicyManager;
|
||||||
private final Looper mLooper;
|
private final Looper mLooper;
|
||||||
@@ -210,7 +214,6 @@ public class Tethering {
|
|||||||
mLog.mark("Tethering.constructed");
|
mLog.mark("Tethering.constructed");
|
||||||
mDeps = deps;
|
mDeps = deps;
|
||||||
mContext = mDeps.getContext();
|
mContext = mDeps.getContext();
|
||||||
mNMService = mDeps.getINetworkManagementService();
|
|
||||||
mStatsService = mDeps.getINetworkStatsService();
|
mStatsService = mDeps.getINetworkStatsService();
|
||||||
mPolicyManager = mDeps.getINetworkPolicyManager();
|
mPolicyManager = mDeps.getINetworkPolicyManager();
|
||||||
mNetd = mDeps.getINetd(mContext);
|
mNetd = mDeps.getINetd(mContext);
|
||||||
@@ -225,10 +228,9 @@ public class Tethering {
|
|||||||
|
|
||||||
mHandler = mTetherMasterSM.getHandler();
|
mHandler = mTetherMasterSM.getHandler();
|
||||||
mOffloadController = new OffloadController(mHandler,
|
mOffloadController = new OffloadController(mHandler,
|
||||||
mDeps.getOffloadHardwareInterface(mHandler, mLog),
|
mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(),
|
||||||
mContext.getContentResolver(), mNMService,
|
mDeps.getINetworkManagementService(), mLog);
|
||||||
mLog);
|
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
|
||||||
mUpstreamNetworkMonitor = deps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
|
|
||||||
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
|
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
|
||||||
mForwardedDownstreams = new HashSet<>();
|
mForwardedDownstreams = new HashSet<>();
|
||||||
|
|
||||||
@@ -421,7 +423,6 @@ public class Tethering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void interfaceRemoved(String iface) {
|
void interfaceRemoved(String iface) {
|
||||||
if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
|
if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
|
||||||
synchronized (mPublicSync) {
|
synchronized (mPublicSync) {
|
||||||
@@ -1022,8 +1023,8 @@ public class Tethering {
|
|||||||
|
|
||||||
String[] ifaces = null;
|
String[] ifaces = null;
|
||||||
try {
|
try {
|
||||||
ifaces = mNMService.listInterfaces();
|
ifaces = mNetd.interfaceGetList();
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
Log.e(TAG, "Error listing Interfaces", e);
|
Log.e(TAG, "Error listing Interfaces", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1282,25 +1283,25 @@ public class Tethering {
|
|||||||
protected boolean turnOnMasterTetherSettings() {
|
protected boolean turnOnMasterTetherSettings() {
|
||||||
final TetheringConfiguration cfg = mConfig;
|
final TetheringConfiguration cfg = mConfig;
|
||||||
try {
|
try {
|
||||||
mNMService.setIpForwardingEnabled(true);
|
mNetd.ipfwdEnableForwarding(TAG);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLog.e(e);
|
mLog.e(e);
|
||||||
transitionTo(mSetIpForwardingEnabledErrorState);
|
transitionTo(mSetIpForwardingEnabledErrorState);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
|
// TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
|
||||||
// Legacy DHCP server is disabled if passed an empty ranges array
|
// Legacy DHCP server is disabled if passed an empty ranges array
|
||||||
final String[] dhcpRanges = cfg.enableLegacyDhcpServer
|
final String[] dhcpRanges = cfg.enableLegacyDhcpServer
|
||||||
? cfg.legacyDhcpRanges
|
? cfg.legacyDhcpRanges : new String[0];
|
||||||
: new String[0];
|
|
||||||
try {
|
try {
|
||||||
// TODO: Find a more accurate method name (startDHCPv4()?).
|
NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
|
||||||
mNMService.startTethering(dhcpRanges);
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
} catch (Exception e) {
|
|
||||||
try {
|
try {
|
||||||
mNMService.stopTethering();
|
// Stop and retry.
|
||||||
mNMService.startTethering(dhcpRanges);
|
mNetd.tetherStop();
|
||||||
} catch (Exception ee) {
|
NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
|
||||||
|
} catch (RemoteException | ServiceSpecificException ee) {
|
||||||
mLog.e(ee);
|
mLog.e(ee);
|
||||||
transitionTo(mStartTetheringErrorState);
|
transitionTo(mStartTetheringErrorState);
|
||||||
return false;
|
return false;
|
||||||
@@ -1312,15 +1313,15 @@ public class Tethering {
|
|||||||
|
|
||||||
protected boolean turnOffMasterTetherSettings() {
|
protected boolean turnOffMasterTetherSettings() {
|
||||||
try {
|
try {
|
||||||
mNMService.stopTethering();
|
mNetd.tetherStop();
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLog.e(e);
|
mLog.e(e);
|
||||||
transitionTo(mStopTetheringErrorState);
|
transitionTo(mStopTetheringErrorState);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mNMService.setIpForwardingEnabled(false);
|
mNetd.ipfwdDisableForwarding(TAG);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
mLog.e(e);
|
mLog.e(e);
|
||||||
transitionTo(mSetIpForwardingDisabledErrorState);
|
transitionTo(mSetIpForwardingDisabledErrorState);
|
||||||
return false;
|
return false;
|
||||||
@@ -1390,12 +1391,13 @@ public class Tethering {
|
|||||||
// TODO: remove this invocation of NetworkUtils.makeStrings().
|
// TODO: remove this invocation of NetworkUtils.makeStrings().
|
||||||
dnsServers = NetworkUtils.makeStrings(dnses);
|
dnsServers = NetworkUtils.makeStrings(dnses);
|
||||||
}
|
}
|
||||||
|
final int netId = (network != null) ? network.netId : NETID_UNSET;
|
||||||
try {
|
try {
|
||||||
mNMService.setDnsForwarders(network, dnsServers);
|
mNetd.tetherDnsSet(netId, dnsServers);
|
||||||
mLog.log(String.format(
|
mLog.log(String.format(
|
||||||
"SET DNS forwarders: network=%s dnsServers=%s",
|
"SET DNS forwarders: network=%s dnsServers=%s",
|
||||||
network, Arrays.toString(dnsServers)));
|
network, Arrays.toString(dnsServers)));
|
||||||
} catch (Exception e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
// TODO: Investigate how this can fail and what exactly
|
// TODO: Investigate how this can fail and what exactly
|
||||||
// happens if/when such failures occur.
|
// happens if/when such failures occur.
|
||||||
mLog.e("setting DNS forwarders failed, " + e);
|
mLog.e("setting DNS forwarders failed, " + e);
|
||||||
@@ -1698,8 +1700,8 @@ public class Tethering {
|
|||||||
Log.e(TAG, "Error in startTethering");
|
Log.e(TAG, "Error in startTethering");
|
||||||
notify(IpServer.CMD_START_TETHERING_ERROR);
|
notify(IpServer.CMD_START_TETHERING_ERROR);
|
||||||
try {
|
try {
|
||||||
mNMService.setIpForwardingEnabled(false);
|
mNetd.ipfwdDisableForwarding(TAG);
|
||||||
} catch (Exception e) { }
|
} catch (RemoteException | ServiceSpecificException e) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1709,8 +1711,8 @@ public class Tethering {
|
|||||||
Log.e(TAG, "Error in stopTethering");
|
Log.e(TAG, "Error in stopTethering");
|
||||||
notify(IpServer.CMD_STOP_TETHERING_ERROR);
|
notify(IpServer.CMD_STOP_TETHERING_ERROR);
|
||||||
try {
|
try {
|
||||||
mNMService.setIpForwardingEnabled(false);
|
mNetd.ipfwdDisableForwarding(TAG);
|
||||||
} catch (Exception e) { }
|
} catch (RemoteException | ServiceSpecificException e) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1720,11 +1722,11 @@ public class Tethering {
|
|||||||
Log.e(TAG, "Error in setDnsForwarders");
|
Log.e(TAG, "Error in setDnsForwarders");
|
||||||
notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
|
notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
|
||||||
try {
|
try {
|
||||||
mNMService.stopTethering();
|
mNetd.tetherStop();
|
||||||
} catch (Exception e) { }
|
} catch (RemoteException | ServiceSpecificException e) { }
|
||||||
try {
|
try {
|
||||||
mNMService.setIpForwardingEnabled(false);
|
mNetd.ipfwdDisableForwarding(TAG);
|
||||||
} catch (Exception e) { }
|
} catch (RemoteException | ServiceSpecificException e) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1884,7 +1886,7 @@ public class Tethering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
|
||||||
// Binder.java closes the resource for us.
|
// Binder.java closes the resource for us.
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
|
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
|
||||||
@@ -2065,7 +2067,7 @@ public class Tethering {
|
|||||||
|
|
||||||
mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
|
mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
|
||||||
final TetherState tetherState = new TetherState(
|
final TetherState tetherState = new TetherState(
|
||||||
new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
|
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mStatsService,
|
||||||
makeControlCallback(), mConfig.enableLegacyDhcpServer,
|
makeControlCallback(), mConfig.enableLegacyDhcpServer,
|
||||||
mDeps.getIpServerDependencies()));
|
mDeps.getIpServerDependencies()));
|
||||||
mTetherStates.put(iface, tetherState);
|
mTetherStates.put(iface, tetherState);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI_P2P;
|
|||||||
import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
|
import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
|
||||||
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_TETHER_IFACE_ERROR;
|
import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
|
||||||
|
import static android.net.INetd.IF_STATE_UP;
|
||||||
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
|
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
|
||||||
import static android.net.ip.IpServer.STATE_AVAILABLE;
|
import static android.net.ip.IpServer.STATE_AVAILABLE;
|
||||||
import static android.net.ip.IpServer.STATE_LOCAL_ONLY;
|
import static android.net.ip.IpServer.STATE_LOCAL_ONLY;
|
||||||
@@ -52,7 +53,7 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.net.INetd;
|
import android.net.INetd;
|
||||||
import android.net.INetworkStatsService;
|
import android.net.INetworkStatsService;
|
||||||
import android.net.InterfaceConfiguration;
|
import android.net.InterfaceConfigurationParcel;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -64,7 +65,6 @@ import android.net.dhcp.IDhcpServerCallbacks;
|
|||||||
import android.net.util.InterfaceParams;
|
import android.net.util.InterfaceParams;
|
||||||
import android.net.util.InterfaceSet;
|
import android.net.util.InterfaceSet;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.INetworkManagementService;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -89,6 +89,8 @@ public class IpServerTest {
|
|||||||
private static final String IFACE_NAME = "testnet1";
|
private static final String IFACE_NAME = "testnet1";
|
||||||
private static final String UPSTREAM_IFACE = "upstream0";
|
private static final String UPSTREAM_IFACE = "upstream0";
|
||||||
private static final String UPSTREAM_IFACE2 = "upstream1";
|
private static final String UPSTREAM_IFACE2 = "upstream1";
|
||||||
|
private static final String BLUETOOTH_IFACE_ADDR = "192.168.42.1";
|
||||||
|
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
|
||||||
private static final int DHCP_LEASE_TIME_SECS = 3600;
|
private static final int DHCP_LEASE_TIME_SECS = 3600;
|
||||||
|
|
||||||
private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
|
private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
|
||||||
@@ -96,11 +98,9 @@ public class IpServerTest {
|
|||||||
|
|
||||||
private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000;
|
private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
@Mock private INetworkManagementService mNMService;
|
|
||||||
@Mock private INetd mNetd;
|
@Mock private INetd mNetd;
|
||||||
@Mock private INetworkStatsService mStatsService;
|
@Mock private INetworkStatsService mStatsService;
|
||||||
@Mock private IpServer.Callback mCallback;
|
@Mock private IpServer.Callback mCallback;
|
||||||
@Mock private InterfaceConfiguration mInterfaceConfiguration;
|
|
||||||
@Mock private SharedLog mSharedLog;
|
@Mock private SharedLog mSharedLog;
|
||||||
@Mock private IDhcpServer mDhcpServer;
|
@Mock private IDhcpServer mDhcpServer;
|
||||||
@Mock private RouterAdvertisementDaemon mRaDaemon;
|
@Mock private RouterAdvertisementDaemon mRaDaemon;
|
||||||
@@ -112,6 +112,7 @@ public class IpServerTest {
|
|||||||
private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor =
|
private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor =
|
||||||
ArgumentCaptor.forClass(LinkProperties.class);
|
ArgumentCaptor.forClass(LinkProperties.class);
|
||||||
private IpServer mIpServer;
|
private IpServer mIpServer;
|
||||||
|
private InterfaceConfigurationParcel mInterfaceConfiguration;
|
||||||
|
|
||||||
private void initStateMachine(int interfaceType) throws Exception {
|
private void initStateMachine(int interfaceType) throws Exception {
|
||||||
initStateMachine(interfaceType, false /* usingLegacyDhcp */);
|
initStateMachine(interfaceType, false /* usingLegacyDhcp */);
|
||||||
@@ -131,17 +132,20 @@ public class IpServerTest {
|
|||||||
}).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
|
}).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
|
||||||
when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
|
when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
|
||||||
when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
|
when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
|
||||||
when(mDependencies.getNetdService()).thenReturn(mNetd);
|
mInterfaceConfiguration = new InterfaceConfigurationParcel();
|
||||||
|
mInterfaceConfiguration.flags = new String[0];
|
||||||
|
if (interfaceType == TETHERING_BLUETOOTH) {
|
||||||
|
mInterfaceConfiguration.ipv4Addr = BLUETOOTH_IFACE_ADDR;
|
||||||
|
mInterfaceConfiguration.prefixLength = BLUETOOTH_DHCP_PREFIX_LENGTH;
|
||||||
|
}
|
||||||
mIpServer = new IpServer(
|
mIpServer = new IpServer(
|
||||||
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog,
|
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mStatsService,
|
||||||
mNMService, mStatsService, mCallback, usingLegacyDhcp, mDependencies);
|
mCallback, usingLegacyDhcp, mDependencies);
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
// Starting the state machine always puts us in a consistent state and notifies
|
// Starting the state machine always puts us in a consistent state and notifies
|
||||||
// the rest of the world that we've changed from an unknown to available state.
|
// the rest of the world that we've changed from an unknown to available state.
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
reset(mNMService, mStatsService, mCallback);
|
reset(mNetd, mStatsService, mCallback);
|
||||||
when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
|
|
||||||
|
|
||||||
when(mRaDaemon.start()).thenReturn(true);
|
when(mRaDaemon.start()).thenReturn(true);
|
||||||
}
|
}
|
||||||
@@ -158,8 +162,7 @@ public class IpServerTest {
|
|||||||
if (upstreamIface != null) {
|
if (upstreamIface != null) {
|
||||||
dispatchTetherConnectionChanged(upstreamIface);
|
dispatchTetherConnectionChanged(upstreamIface);
|
||||||
}
|
}
|
||||||
reset(mNMService, mStatsService, mCallback);
|
reset(mNetd, mStatsService, mCallback);
|
||||||
when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before public void setUp() throws Exception {
|
@Before public void setUp() throws Exception {
|
||||||
@@ -169,15 +172,14 @@ public class IpServerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void startsOutAvailable() {
|
public void startsOutAvailable() {
|
||||||
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(),
|
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
|
||||||
TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mCallback,
|
mNetd, mStatsService, mCallback, false /* usingLegacyDhcp */, mDependencies);
|
||||||
false /* usingLegacyDhcp */, mDependencies);
|
|
||||||
mIpServer.start();
|
mIpServer.start();
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mCallback).updateInterfaceState(
|
verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
|
verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
|
||||||
verifyNoMoreInteractions(mCallback, mNMService, mStatsService);
|
verifyNoMoreInteractions(mCallback, mNetd, mStatsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -196,7 +198,7 @@ public class IpServerTest {
|
|||||||
// None of these commands should trigger us to request action from
|
// None of these commands should trigger us to request action from
|
||||||
// the rest of the system.
|
// the rest of the system.
|
||||||
dispatchCommand(command);
|
dispatchCommand(command);
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ public class IpServerTest {
|
|||||||
verify(mCallback).updateInterfaceState(
|
verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
|
verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class));
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -216,13 +218,17 @@ public class IpServerTest {
|
|||||||
initStateMachine(TETHERING_BLUETOOTH);
|
initStateMachine(TETHERING_BLUETOOTH);
|
||||||
|
|
||||||
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
||||||
InOrder inOrder = inOrder(mCallback, mNMService);
|
InOrder inOrder = inOrder(mCallback, mNetd);
|
||||||
inOrder.verify(mNMService).tetherInterface(IFACE_NAME);
|
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
|
||||||
|
// One for ipv4 route, one for ipv6 link local route.
|
||||||
|
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
|
||||||
|
any(), any());
|
||||||
inOrder.verify(mCallback).updateInterfaceState(
|
inOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), any(LinkProperties.class));
|
eq(mIpServer), any(LinkProperties.class));
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -230,14 +236,16 @@ public class IpServerTest {
|
|||||||
initTetheredStateMachine(TETHERING_BLUETOOTH, null);
|
initTetheredStateMachine(TETHERING_BLUETOOTH, null);
|
||||||
|
|
||||||
dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
|
dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
|
||||||
InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback);
|
InOrder inOrder = inOrder(mNetd, mStatsService, mCallback);
|
||||||
inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
|
inOrder.verify(mNetd).tetherApplyDnsInterfaces();
|
||||||
|
inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
|
||||||
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
inOrder.verify(mCallback).updateInterfaceState(
|
inOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), any(LinkProperties.class));
|
eq(mIpServer), any(LinkProperties.class));
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -245,16 +253,19 @@ public class IpServerTest {
|
|||||||
initStateMachine(TETHERING_USB);
|
initStateMachine(TETHERING_USB);
|
||||||
|
|
||||||
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
||||||
InOrder inOrder = inOrder(mCallback, mNMService);
|
InOrder inOrder = inOrder(mCallback, mNetd);
|
||||||
inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME);
|
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
|
||||||
inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration);
|
IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
|
||||||
inOrder.verify(mNMService).tetherInterface(IFACE_NAME);
|
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
|
||||||
|
any(), any());
|
||||||
inOrder.verify(mCallback).updateInterfaceState(
|
inOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
||||||
assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
|
assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -262,16 +273,19 @@ public class IpServerTest {
|
|||||||
initStateMachine(TETHERING_WIFI_P2P);
|
initStateMachine(TETHERING_WIFI_P2P);
|
||||||
|
|
||||||
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
|
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
|
||||||
InOrder inOrder = inOrder(mCallback, mNMService);
|
InOrder inOrder = inOrder(mCallback, mNetd);
|
||||||
inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME);
|
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
|
||||||
inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration);
|
IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
|
||||||
inOrder.verify(mNMService).tetherInterface(IFACE_NAME);
|
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
|
||||||
|
any(), any());
|
||||||
inOrder.verify(mCallback).updateInterfaceState(
|
inOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_LOCAL_ONLY, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_LOCAL_ONLY, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
eq(mIpServer), mLinkPropertiesCaptor.capture());
|
||||||
assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
|
assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue());
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -281,10 +295,10 @@ public class IpServerTest {
|
|||||||
// Telling the state machine about its upstream interface triggers
|
// Telling the state machine about its upstream interface triggers
|
||||||
// a little more configuration.
|
// a little more configuration.
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||||
InOrder inOrder = inOrder(mNMService);
|
InOrder inOrder = inOrder(mNetd);
|
||||||
inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -292,49 +306,49 @@ public class IpServerTest {
|
|||||||
initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
|
initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
|
||||||
|
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
||||||
InOrder inOrder = inOrder(mNMService, mStatsService);
|
InOrder inOrder = inOrder(mNetd, mStatsService);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handlesChangingUpstreamNatFailure() throws Exception {
|
public void handlesChangingUpstreamNatFailure() throws Exception {
|
||||||
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
||||||
|
|
||||||
doThrow(RemoteException.class).when(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
doThrow(RemoteException.class).when(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
|
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
||||||
InOrder inOrder = inOrder(mNMService, mStatsService);
|
InOrder inOrder = inOrder(mNetd, mStatsService);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handlesChangingUpstreamInterfaceForwardingFailure() throws Exception {
|
public void handlesChangingUpstreamInterfaceForwardingFailure() throws Exception {
|
||||||
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
||||||
|
|
||||||
doThrow(RemoteException.class).when(mNMService).startInterfaceForwarding(
|
doThrow(RemoteException.class).when(mNetd).ipfwdAddInterfaceForward(
|
||||||
IFACE_NAME, UPSTREAM_IFACE2);
|
IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
|
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
|
||||||
InOrder inOrder = inOrder(mNMService, mStatsService);
|
InOrder inOrder = inOrder(mNetd, mStatsService);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE2);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -342,17 +356,19 @@ public class IpServerTest {
|
|||||||
initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
|
initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
|
||||||
|
|
||||||
dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
|
dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
|
||||||
InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback);
|
InOrder inOrder = inOrder(mNetd, mStatsService, mCallback);
|
||||||
inOrder.verify(mStatsService).forceUpdate();
|
inOrder.verify(mStatsService).forceUpdate();
|
||||||
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
|
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
|
inOrder.verify(mNetd).tetherApplyDnsInterfaces();
|
||||||
|
inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
|
||||||
|
inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
|
||||||
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
inOrder.verify(mCallback).updateInterfaceState(
|
inOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
inOrder.verify(mCallback).updateLinkProperties(
|
inOrder.verify(mCallback).updateLinkProperties(
|
||||||
eq(mIpServer), any(LinkProperties.class));
|
eq(mIpServer), any(LinkProperties.class));
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -361,13 +377,14 @@ public class IpServerTest {
|
|||||||
initTetheredStateMachine(TETHERING_USB, null);
|
initTetheredStateMachine(TETHERING_USB, null);
|
||||||
|
|
||||||
if (shouldThrow) {
|
if (shouldThrow) {
|
||||||
doThrow(RemoteException.class).when(mNMService).untetherInterface(IFACE_NAME);
|
doThrow(RemoteException.class).when(mNetd).tetherInterfaceRemove(IFACE_NAME);
|
||||||
}
|
}
|
||||||
dispatchCommand(IpServer.CMD_INTERFACE_DOWN);
|
dispatchCommand(IpServer.CMD_INTERFACE_DOWN);
|
||||||
InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback);
|
InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
|
||||||
usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
|
// Currently IpServer interfaceSetCfg twice to stop IPv4. One just set interface down
|
||||||
usbTeardownOrder.verify(mNMService).setInterfaceConfig(
|
// Another one is set IPv4 to 0.0.0.0/0 as clearng ipv4 address.
|
||||||
IFACE_NAME, mInterfaceConfiguration);
|
usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
|
||||||
|
argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
|
mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
|
||||||
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
||||||
@@ -380,12 +397,15 @@ public class IpServerTest {
|
|||||||
public void usbShouldBeTornDownOnTetherError() throws Exception {
|
public void usbShouldBeTornDownOnTetherError() throws Exception {
|
||||||
initStateMachine(TETHERING_USB);
|
initStateMachine(TETHERING_USB);
|
||||||
|
|
||||||
doThrow(RemoteException.class).when(mNMService).tetherInterface(IFACE_NAME);
|
doThrow(RemoteException.class).when(mNetd).tetherInterfaceAdd(IFACE_NAME);
|
||||||
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
|
||||||
InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback);
|
InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
|
||||||
usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
|
usbTeardownOrder.verify(mNetd).interfaceSetCfg(
|
||||||
usbTeardownOrder.verify(mNMService).setInterfaceConfig(
|
argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
IFACE_NAME, mInterfaceConfiguration);
|
usbTeardownOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
|
||||||
|
|
||||||
|
usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
|
||||||
|
argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR);
|
||||||
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
||||||
@@ -397,11 +417,13 @@ public class IpServerTest {
|
|||||||
public void shouldTearDownUsbOnUpstreamError() throws Exception {
|
public void shouldTearDownUsbOnUpstreamError() throws Exception {
|
||||||
initTetheredStateMachine(TETHERING_USB, null);
|
initTetheredStateMachine(TETHERING_USB, null);
|
||||||
|
|
||||||
doThrow(RemoteException.class).when(mNMService).enableNat(anyString(), anyString());
|
doThrow(RemoteException.class).when(mNetd).tetherAddForward(anyString(), anyString());
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||||
InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback);
|
InOrder usbTeardownOrder = inOrder(mNetd, mCallback);
|
||||||
usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
|
usbTeardownOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE);
|
||||||
usbTeardownOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration);
|
|
||||||
|
usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
|
||||||
|
argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
|
||||||
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
usbTeardownOrder.verify(mCallback).updateInterfaceState(
|
||||||
mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR);
|
mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR);
|
||||||
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
usbTeardownOrder.verify(mCallback).updateLinkProperties(
|
||||||
@@ -413,11 +435,11 @@ public class IpServerTest {
|
|||||||
public void ignoresDuplicateUpstreamNotifications() throws Exception {
|
public void ignoresDuplicateUpstreamNotifications() throws Exception {
|
||||||
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
|
||||||
|
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||||
verifyNoMoreInteractions(mNMService, mStatsService, mCallback);
|
verifyNoMoreInteractions(mNetd, mStatsService, mCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,4 +547,12 @@ public class IpServerTest {
|
|||||||
// never see an empty interface name in any LinkProperties update.
|
// never see an empty interface name in any LinkProperties update.
|
||||||
assertFalse(TextUtils.isEmpty(lp.getInterfaceName()));
|
assertFalse(TextUtils.isEmpty(lp.getInterfaceName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean assertContainsFlag(String[] flags, String match) {
|
||||||
|
for (String flag : flags) {
|
||||||
|
if (flag.equals(match)) return true;
|
||||||
|
}
|
||||||
|
fail("Missing flag: " + match);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import static org.mockito.Matchers.anyInt;
|
|||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
@@ -74,7 +73,7 @@ import android.net.INetworkPolicyManager;
|
|||||||
import android.net.INetworkStatsService;
|
import android.net.INetworkStatsService;
|
||||||
import android.net.ITetheringEventCallback;
|
import android.net.ITetheringEventCallback;
|
||||||
import android.net.InetAddresses;
|
import android.net.InetAddresses;
|
||||||
import android.net.InterfaceConfiguration;
|
import android.net.InterfaceConfigurationParcel;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -147,6 +146,7 @@ public class TetheringTest {
|
|||||||
private static final String TEST_USB_IFNAME = "test_rndis0";
|
private static final String TEST_USB_IFNAME = "test_rndis0";
|
||||||
private static final String TEST_WLAN_IFNAME = "test_wlan0";
|
private static final String TEST_WLAN_IFNAME = "test_wlan0";
|
||||||
private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
|
private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
|
||||||
|
private static final String TETHERING_NAME = "Tethering";
|
||||||
|
|
||||||
private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
|
private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
@@ -185,6 +185,7 @@ public class TetheringTest {
|
|||||||
private BroadcastReceiver mBroadcastReceiver;
|
private BroadcastReceiver mBroadcastReceiver;
|
||||||
private Tethering mTethering;
|
private Tethering mTethering;
|
||||||
private PhoneStateListener mPhoneStateListener;
|
private PhoneStateListener mPhoneStateListener;
|
||||||
|
private InterfaceConfigurationParcel mInterfaceConfiguration;
|
||||||
|
|
||||||
private class TestContext extends BroadcastInterceptingContext {
|
private class TestContext extends BroadcastInterceptingContext {
|
||||||
TestContext(Context base) {
|
TestContext(Context base) {
|
||||||
@@ -247,11 +248,6 @@ public class TetheringTest {
|
|||||||
MacAddress.ALL_ZEROS_ADDRESS);
|
MacAddress.ALL_ZEROS_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public INetd getNetdService() {
|
|
||||||
return mNetd;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
|
public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
|
||||||
DhcpServerCallbacks cb) {
|
DhcpServerCallbacks cb) {
|
||||||
@@ -429,11 +425,11 @@ public class TetheringTest {
|
|||||||
.thenReturn(new int[0]);
|
.thenReturn(new int[0]);
|
||||||
when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
|
when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
|
||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
when(mNMService.listInterfaces())
|
when(mNetd.interfaceGetList())
|
||||||
.thenReturn(new String[] {
|
.thenReturn(new String[] {
|
||||||
TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME});
|
TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME});
|
||||||
when(mNMService.getInterfaceConfig(anyString()))
|
mInterfaceConfiguration = new InterfaceConfigurationParcel();
|
||||||
.thenReturn(new InterfaceConfiguration());
|
mInterfaceConfiguration.flags = new String[0];
|
||||||
when(mRouterAdvertisementDaemon.start())
|
when(mRouterAdvertisementDaemon.start())
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
|
|
||||||
@@ -523,10 +519,11 @@ public class TetheringTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
|
private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
|
||||||
verify(mNMService, times(1)).getInterfaceConfig(ifname);
|
verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, times(1))
|
verify(mNetd, times(1)).tetherInterfaceAdd(ifname);
|
||||||
.setInterfaceConfig(eq(ifname), any(InterfaceConfiguration.class));
|
verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
|
||||||
verify(mNMService, times(1)).tetherInterface(ifname);
|
verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
|
||||||
|
anyString(), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyTetheringBroadcast(String ifname, String whichExtra) {
|
private void verifyTetheringBroadcast(String ifname, String whichExtra) {
|
||||||
@@ -558,7 +555,7 @@ public class TetheringTest {
|
|||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
}
|
}
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,14 +578,14 @@ public class TetheringTest {
|
|||||||
prepareUsbTethering(upstreamState);
|
prepareUsbTethering(upstreamState);
|
||||||
|
|
||||||
// This should produce no activity of any kind.
|
// This should produce no activity of any kind.
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// Pretend we then receive USB configured broadcast.
|
// Pretend we then receive USB configured broadcast.
|
||||||
sendUsbBroadcast(true, true, true);
|
sendUsbBroadcast(true, true, true);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
// Now we should see the start of tethering mechanics (in this case:
|
// Now we should see the start of tethering mechanics (in this case:
|
||||||
// tetherMatchingInterfaces() which starts by fetching all interfaces).
|
// tetherMatchingInterfaces() which starts by fetching all interfaces).
|
||||||
verify(mNMService, times(1)).listInterfaces();
|
verify(mNetd, times(1)).interfaceGetList();
|
||||||
|
|
||||||
// UpstreamNetworkMonitor should receive selected upstream
|
// UpstreamNetworkMonitor should receive selected upstream
|
||||||
verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
|
verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
|
||||||
@@ -618,9 +615,9 @@ public class TetheringTest {
|
|||||||
|
|
||||||
verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
|
verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
|
||||||
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
verify(mNMService, times(1)).startTethering(any(String[].class));
|
verify(mNetd, times(1)).tetherStartWithConfiguration(any());
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
@@ -638,16 +635,16 @@ public class TetheringTest {
|
|||||||
mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
|
mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
|
verify(mNetd, times(1)).tetherApplyDnsInterfaces();
|
||||||
// {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
|
verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
|
||||||
verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
|
verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
|
||||||
verify(mNMService, times(2))
|
// interfaceSetCfg() called once for enabling and twice disabling IPv4.
|
||||||
.setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, times(1)).stopTethering();
|
verify(mNetd, times(1)).tetherStop();
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(false);
|
verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
|
||||||
verify(mWifiManager, times(3)).updateInterfaceIpState(
|
verify(mWifiManager, times(3)).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
// Asking for the last error after the per-interface state machine
|
// Asking for the last error after the per-interface state machine
|
||||||
// has been reaped yields an unknown interface error.
|
// has been reaped yields an unknown interface error.
|
||||||
@@ -684,8 +681,8 @@ public class TetheringTest {
|
|||||||
UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
|
|
||||||
sendIPv6TetherUpdates(upstreamState);
|
sendIPv6TetherUpdates(upstreamState);
|
||||||
verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
|
verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
|
||||||
@@ -708,8 +705,8 @@ public class TetheringTest {
|
|||||||
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
|
|
||||||
sendIPv6TetherUpdates(upstreamState);
|
sendIPv6TetherUpdates(upstreamState);
|
||||||
verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
|
verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
|
||||||
@@ -721,8 +718,8 @@ public class TetheringTest {
|
|||||||
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mRouterAdvertisementDaemon, times(1)).start();
|
verify(mRouterAdvertisementDaemon, times(1)).start();
|
||||||
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
||||||
|
|
||||||
@@ -736,12 +733,11 @@ public class TetheringTest {
|
|||||||
UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
|
UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
TEST_XLAT_MOBILE_IFNAME);
|
|
||||||
|
|
||||||
sendIPv6TetherUpdates(upstreamState);
|
sendIPv6TetherUpdates(upstreamState);
|
||||||
verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
|
verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
|
||||||
@@ -754,9 +750,9 @@ public class TetheringTest {
|
|||||||
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
|
||||||
runUsbTethering(upstreamState);
|
runUsbTethering(upstreamState);
|
||||||
|
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
|
|
||||||
// Then 464xlat comes up
|
// Then 464xlat comes up
|
||||||
upstreamState = buildMobile464xlatUpstreamState();
|
upstreamState = buildMobile464xlatUpstreamState();
|
||||||
@@ -772,12 +768,11 @@ public class TetheringTest {
|
|||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
// Forwarding is added for 464xlat
|
// Forwarding is added for 464xlat
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
|
||||||
TEST_XLAT_MOBILE_IFNAME);
|
|
||||||
// Forwarding was not re-added for v6 (still times(1))
|
// Forwarding was not re-added for v6 (still times(1))
|
||||||
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
|
||||||
// DHCP not restarted on downstream (still times(1))
|
// DHCP not restarted on downstream (still times(1))
|
||||||
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
|
||||||
}
|
}
|
||||||
@@ -820,7 +815,7 @@ public class TetheringTest {
|
|||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// Emulate externally-visible WifiManager effects, causing the
|
// Emulate externally-visible WifiManager effects, causing the
|
||||||
// per-interface state machine to start up, and telling us that
|
// per-interface state machine to start up, and telling us that
|
||||||
@@ -833,7 +828,7 @@ public class TetheringTest {
|
|||||||
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -847,7 +842,7 @@ public class TetheringTest {
|
|||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// Emulate externally-visible WifiManager effects, causing the
|
// Emulate externally-visible WifiManager effects, causing the
|
||||||
// per-interface state machine to start up, and telling us that
|
// per-interface state machine to start up, and telling us that
|
||||||
@@ -858,9 +853,11 @@ public class TetheringTest {
|
|||||||
|
|
||||||
verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
|
verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
|
||||||
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
verify(mNMService, times(1)).startTethering(any(String[].class));
|
verify(mNetd, times(1)).tetherStartWithConfiguration(any());
|
||||||
verifyNoMoreInteractions(mNMService);
|
verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
|
||||||
|
anyString(), anyString());
|
||||||
|
verifyNoMoreInteractions(mNetd);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
@@ -878,8 +875,8 @@ public class TetheringTest {
|
|||||||
/////
|
/////
|
||||||
// We do not currently emulate any upstream being found.
|
// We do not currently emulate any upstream being found.
|
||||||
//
|
//
|
||||||
// This is why there are no calls to verify mNMService.enableNat() or
|
// This is why there are no calls to verify mNetd.tetherAddForward() or
|
||||||
// mNMService.startInterfaceForwarding().
|
// mNetd.ipfwdAddInterfaceForward().
|
||||||
/////
|
/////
|
||||||
|
|
||||||
// Emulate pressing the WiFi tethering button.
|
// Emulate pressing the WiFi tethering button.
|
||||||
@@ -887,7 +884,7 @@ public class TetheringTest {
|
|||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).stopSoftAp();
|
verify(mWifiManager, times(1)).stopSoftAp();
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// Emulate externally-visible WifiManager effects, when tethering mode
|
// Emulate externally-visible WifiManager effects, when tethering mode
|
||||||
// is being torn down.
|
// is being torn down.
|
||||||
@@ -895,16 +892,16 @@ public class TetheringTest {
|
|||||||
mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
|
mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
|
verify(mNetd, times(1)).tetherApplyDnsInterfaces();
|
||||||
// {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
|
verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
|
||||||
verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME);
|
verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
|
||||||
verify(mNMService, atLeastOnce())
|
// interfaceSetCfg() called once for enabling and twice for disabling IPv4.
|
||||||
.setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, times(1)).stopTethering();
|
verify(mNetd, times(1)).tetherStop();
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(false);
|
verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
|
||||||
verify(mWifiManager, times(3)).updateInterfaceIpState(
|
verify(mWifiManager, times(3)).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
// Asking for the last error after the per-interface state machine
|
// Asking for the last error after the per-interface state machine
|
||||||
// has been reaped yields an unknown interface error.
|
// has been reaped yields an unknown interface error.
|
||||||
@@ -915,14 +912,14 @@ public class TetheringTest {
|
|||||||
@Test
|
@Test
|
||||||
public void failureEnablingIpForwarding() throws Exception {
|
public void failureEnablingIpForwarding() throws Exception {
|
||||||
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
|
||||||
doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);
|
doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
|
|
||||||
// Emulate pressing the WiFi tethering button.
|
// Emulate pressing the WiFi tethering button.
|
||||||
mTethering.startTethering(TETHERING_WIFI, null, false);
|
mTethering.startTethering(TETHERING_WIFI, null, false);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
verify(mWifiManager, times(1)).startTetheredHotspot(null);
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// Emulate externally-visible WifiManager effects, causing the
|
// Emulate externally-visible WifiManager effects, causing the
|
||||||
// per-interface state machine to start up, and telling us that
|
// per-interface state machine to start up, and telling us that
|
||||||
@@ -931,15 +928,15 @@ public class TetheringTest {
|
|||||||
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
|
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
// We verify get/set called thrice here: twice for setup (on NMService) and once during
|
// We verify get/set called three times here: twice for setup and once during
|
||||||
// teardown (on Netd) because all events happen over the course of the single
|
// teardown because all events happen over the course of the single
|
||||||
// dispatchAll() above. Note that once the IpServer IPv4 address config
|
// dispatchAll() above. Note that once the IpServer IPv4 address config
|
||||||
// code is refactored the two calls during shutdown will revert to one.
|
// code is refactored the two calls during shutdown will revert to one.
|
||||||
verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
|
verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
|
||||||
verify(mNMService, times(2))
|
verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
|
||||||
.setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
|
||||||
verify(mNetd, times(1)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
|
verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
|
||||||
verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
|
anyString(), anyString());
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
@@ -949,18 +946,20 @@ public class TetheringTest {
|
|||||||
assertEquals(3, mTetheringDependencies.mIsTetheringSupportedCalls);
|
assertEquals(3, mTetheringDependencies.mIsTetheringSupportedCalls);
|
||||||
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
|
||||||
// This is called, but will throw.
|
// This is called, but will throw.
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
// This never gets called because of the exception thrown above.
|
// This never gets called because of the exception thrown above.
|
||||||
verify(mNMService, times(0)).startTethering(any(String[].class));
|
verify(mNetd, times(0)).tetherStartWithConfiguration(any());
|
||||||
// When the master state machine transitions to an error state it tells
|
// When the master state machine transitions to an error state it tells
|
||||||
// downstream interfaces, which causes us to tell Wi-Fi about the error
|
// downstream interfaces, which causes us to tell Wi-Fi about the error
|
||||||
// so it can take down AP mode.
|
// so it can take down AP mode.
|
||||||
verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
|
verify(mNetd, times(1)).tetherApplyDnsInterfaces();
|
||||||
|
verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
|
||||||
|
verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
|
||||||
verify(mWifiManager).updateInterfaceIpState(
|
verify(mWifiManager).updateInterfaceIpState(
|
||||||
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
|
TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
|
||||||
|
|
||||||
verifyNoMoreInteractions(mWifiManager);
|
verifyNoMoreInteractions(mWifiManager);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runUserRestrictionsChange(
|
private void runUserRestrictionsChange(
|
||||||
@@ -1232,9 +1231,9 @@ public class TetheringTest {
|
|||||||
|
|
||||||
verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
|
verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
|
||||||
verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
|
verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(true);
|
verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
verify(mNMService, times(1)).startTethering(any(String[].class));
|
verify(mNetd, times(1)).tetherStartWithConfiguration(any());
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
|
verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
|
||||||
verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
|
verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
|
||||||
// This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
|
// This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
|
||||||
@@ -1249,16 +1248,16 @@ public class TetheringTest {
|
|||||||
mTethering.interfaceRemoved(TEST_P2P_IFNAME);
|
mTethering.interfaceRemoved(TEST_P2P_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, times(1)).untetherInterface(TEST_P2P_IFNAME);
|
verify(mNetd, times(1)).tetherApplyDnsInterfaces();
|
||||||
// {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
|
verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
|
||||||
verify(mNMService, times(2)).getInterfaceConfig(TEST_P2P_IFNAME);
|
verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
|
||||||
verify(mNMService, times(2))
|
// interfaceSetCfg() called once for enabling and twice for disabling IPv4.
|
||||||
.setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, times(1)).stopTethering();
|
verify(mNetd, times(1)).tetherStop();
|
||||||
verify(mNMService, times(1)).setIpForwardingEnabled(false);
|
verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
|
||||||
verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
|
verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
|
||||||
verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
|
verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
// Asking for the last error after the per-interface state machine
|
// Asking for the last error after the per-interface state machine
|
||||||
// has been reaped yields an unknown interface error.
|
// has been reaped yields an unknown interface error.
|
||||||
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
||||||
@@ -1272,12 +1271,11 @@ public class TetheringTest {
|
|||||||
sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
|
sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
|
verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, never())
|
verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
|
||||||
.setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
|
||||||
verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
|
verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
verify(mNMService, never()).setIpForwardingEnabled(true);
|
verify(mNetd, never()).tetherStartWithConfiguration(any());
|
||||||
verify(mNMService, never()).startTethering(any(String[].class));
|
|
||||||
|
|
||||||
// Emulate externally-visible WifiP2pManager effects, when wifi p2p group
|
// Emulate externally-visible WifiP2pManager effects, when wifi p2p group
|
||||||
// is being removed.
|
// is being removed.
|
||||||
@@ -1285,13 +1283,13 @@ public class TetheringTest {
|
|||||||
mTethering.interfaceRemoved(TEST_P2P_IFNAME);
|
mTethering.interfaceRemoved(TEST_P2P_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, never()).untetherInterface(TEST_P2P_IFNAME);
|
verify(mNetd, never()).tetherApplyDnsInterfaces();
|
||||||
verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
|
verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
|
||||||
verify(mNMService, never())
|
verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
|
||||||
.setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, never()).stopTethering();
|
verify(mNetd, never()).tetherStop();
|
||||||
verify(mNMService, never()).setIpForwardingEnabled(false);
|
verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
|
||||||
verifyNoMoreInteractions(mNMService);
|
verifyNoMoreInteractions(mNetd);
|
||||||
// Asking for the last error after the per-interface state machine
|
// Asking for the last error after the per-interface state machine
|
||||||
// has been reaped yields an unknown interface error.
|
// has been reaped yields an unknown interface error.
|
||||||
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
||||||
@@ -1321,12 +1319,11 @@ public class TetheringTest {
|
|||||||
sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
|
sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
|
||||||
mLooper.dispatchAll();
|
mLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
|
verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
|
||||||
verify(mNMService, never())
|
verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
|
||||||
.setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
|
verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
|
||||||
verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
|
verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
|
||||||
verify(mNMService, never()).setIpForwardingEnabled(true);
|
verify(mNetd, never()).tetherStartWithConfiguration(any());
|
||||||
verify(mNMService, never()).startTethering(any(String[].class));
|
|
||||||
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user