Merge "Test tethered callback with TetheringInterface"
This commit is contained in:
@@ -80,6 +80,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -349,7 +350,7 @@ public class EthernetTetheringTest {
|
|||||||
private final CountDownLatch mLocalOnlyStartedLatch = new CountDownLatch(1);
|
private final CountDownLatch mLocalOnlyStartedLatch = new CountDownLatch(1);
|
||||||
private final CountDownLatch mLocalOnlyStoppedLatch = new CountDownLatch(1);
|
private final CountDownLatch mLocalOnlyStoppedLatch = new CountDownLatch(1);
|
||||||
private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
|
private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
|
||||||
private final String mIface;
|
private final TetheringInterface mIface;
|
||||||
|
|
||||||
private volatile boolean mInterfaceWasTethered = false;
|
private volatile boolean mInterfaceWasTethered = false;
|
||||||
private volatile boolean mInterfaceWasLocalOnly = false;
|
private volatile boolean mInterfaceWasLocalOnly = false;
|
||||||
@@ -358,20 +359,24 @@ public class EthernetTetheringTest {
|
|||||||
|
|
||||||
MyTetheringEventCallback(TetheringManager tm, String iface) {
|
MyTetheringEventCallback(TetheringManager tm, String iface) {
|
||||||
mTm = tm;
|
mTm = tm;
|
||||||
mIface = iface;
|
mIface = new TetheringInterface(TETHERING_ETHERNET, iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister() {
|
public void unregister() {
|
||||||
mTm.unregisterTetheringEventCallback(this);
|
mTm.unregisterTetheringEventCallback(this);
|
||||||
mUnregistered = true;
|
mUnregistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTetheredInterfacesChanged(List<String> interfaces) {
|
public void onTetheredInterfacesChanged(List<String> interfaces) {
|
||||||
|
fail("Should only call callback that takes a Set<TetheringInterface>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetheredInterfacesChanged(Set<TetheringInterface> interfaces) {
|
||||||
// Ignore stale callbacks registered by previous test cases.
|
// Ignore stale callbacks registered by previous test cases.
|
||||||
if (mUnregistered) return;
|
if (mUnregistered) return;
|
||||||
|
|
||||||
if (!mInterfaceWasTethered && (mIface == null || interfaces.contains(mIface))) {
|
if (!mInterfaceWasTethered && interfaces.contains(mIface)) {
|
||||||
// This interface is being tethered for the first time.
|
// This interface is being tethered for the first time.
|
||||||
Log.d(TAG, "Tethering started: " + interfaces);
|
Log.d(TAG, "Tethering started: " + interfaces);
|
||||||
mInterfaceWasTethered = true;
|
mInterfaceWasTethered = true;
|
||||||
@@ -384,10 +389,15 @@ public class EthernetTetheringTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocalOnlyInterfacesChanged(List<String> interfaces) {
|
public void onLocalOnlyInterfacesChanged(List<String> interfaces) {
|
||||||
|
fail("Should only call callback that takes a Set<TetheringInterface>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLocalOnlyInterfacesChanged(Set<TetheringInterface> interfaces) {
|
||||||
// Ignore stale callbacks registered by previous test cases.
|
// Ignore stale callbacks registered by previous test cases.
|
||||||
if (mUnregistered) return;
|
if (mUnregistered) return;
|
||||||
|
|
||||||
if (!mInterfaceWasLocalOnly && (mIface == null || interfaces.contains(mIface))) {
|
if (!mInterfaceWasLocalOnly && interfaces.contains(mIface)) {
|
||||||
// This interface is being put into local-only mode for the first time.
|
// This interface is being put into local-only mode for the first time.
|
||||||
Log.d(TAG, "Local-only started: " + interfaces);
|
Log.d(TAG, "Local-only started: " + interfaces);
|
||||||
mInterfaceWasLocalOnly = true;
|
mInterfaceWasLocalOnly = true;
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ import static android.Manifest.permission.NETWORK_SETTINGS;
|
|||||||
import static android.Manifest.permission.READ_DEVICE_CONFIG;
|
import static android.Manifest.permission.READ_DEVICE_CONFIG;
|
||||||
import static android.Manifest.permission.TETHER_PRIVILEGED;
|
import static android.Manifest.permission.TETHER_PRIVILEGED;
|
||||||
import static android.Manifest.permission.WRITE_SETTINGS;
|
import static android.Manifest.permission.WRITE_SETTINGS;
|
||||||
|
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||||
import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported;
|
import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported;
|
||||||
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
|
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
|
||||||
|
|
||||||
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
|
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
@@ -35,6 +35,7 @@ import android.app.UiAutomation;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
|
import android.net.TetheringInterface;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.cts.util.CtsTetheringUtils;
|
import android.net.cts.util.CtsTetheringUtils;
|
||||||
import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
|
import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
|
||||||
@@ -102,12 +103,13 @@ public class TetheringModuleTest {
|
|||||||
try {
|
try {
|
||||||
tetherEventCallback.assumeTetheringSupported();
|
tetherEventCallback.assumeTetheringSupported();
|
||||||
assumeTrue(isWifiTetheringSupported(tetherEventCallback));
|
assumeTrue(isWifiTetheringSupported(tetherEventCallback));
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
|
||||||
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
final TetheringInterface tetheredIface =
|
||||||
|
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
||||||
|
|
||||||
final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
|
assertNotNull(tetheredIface);
|
||||||
assertEquals(1, tetheredIfaces.size());
|
final String wifiTetheringIface = tetheredIface.getInterface();
|
||||||
final String wifiTetheringIface = tetheredIfaces.get(0);
|
|
||||||
|
|
||||||
NetworkInterface nif = NetworkInterface.getByName(wifiTetheringIface);
|
NetworkInterface nif = NetworkInterface.getByName(wifiTetheringIface);
|
||||||
// Tethering downstream only have one ipv4 address.
|
// Tethering downstream only have one ipv4 address.
|
||||||
@@ -120,11 +122,11 @@ public class TetheringModuleTest {
|
|||||||
tnt = setUpTestNetwork(
|
tnt = setUpTestNetwork(
|
||||||
new LinkAddress(testPrefix.getAddress(), testPrefix.getPrefixLength()));
|
new LinkAddress(testPrefix.getAddress(), testPrefix.getPrefixLength()));
|
||||||
|
|
||||||
tetherEventCallback.expectTetheredInterfacesChanged(null);
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
final List<String> wifiRegexs =
|
final List<String> wifiRegexs =
|
||||||
tetherEventCallback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
|
tetherEventCallback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
|
||||||
|
|
||||||
tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs);
|
tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs, TETHERING_WIFI);
|
||||||
nif = NetworkInterface.getByName(wifiTetheringIface);
|
nif = NetworkInterface.getByName(wifiTetheringIface);
|
||||||
final LinkAddress newHotspotAddr = getFirstIpv4Address(nif);
|
final LinkAddress newHotspotAddr = getFirstIpv4Address(nif);
|
||||||
assertNotNull(newHotspotAddr);
|
assertNotNull(newHotspotAddr);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
|
|||||||
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
|
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
|
||||||
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
|
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
@@ -35,6 +35,7 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.TetheredClient;
|
import android.net.TetheredClient;
|
||||||
|
import android.net.TetheringInterface;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.TetheringManager.TetheringEventCallback;
|
import android.net.TetheringManager.TetheringEventCallback;
|
||||||
import android.net.TetheringManager.TetheringInterfaceRegexps;
|
import android.net.TetheringManager.TetheringInterfaceRegexps;
|
||||||
@@ -51,6 +52,7 @@ import com.android.net.module.util.ArrayTrackRecord;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public final class CtsTetheringUtils {
|
public final class CtsTetheringUtils {
|
||||||
private TetheringManager mTm;
|
private TetheringManager mTm;
|
||||||
@@ -116,23 +118,38 @@ public final class CtsTetheringUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIfaceMatch(final List<String> ifaceRegexs, final List<String> ifaces) {
|
private static boolean isRegexMatch(final String[] ifaceRegexs, String iface) {
|
||||||
return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIfaceMatch(final String[] ifaceRegexs, final List<String> ifaces) {
|
|
||||||
if (ifaceRegexs == null) fail("ifaceRegexs should not be null");
|
if (ifaceRegexs == null) fail("ifaceRegexs should not be null");
|
||||||
|
|
||||||
|
for (String regex : ifaceRegexs) {
|
||||||
|
if (iface.matches(regex)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAnyIfaceMatch(final String[] ifaceRegexs, final List<String> ifaces) {
|
||||||
if (ifaces == null) return false;
|
if (ifaces == null) return false;
|
||||||
|
|
||||||
for (String s : ifaces) {
|
for (String s : ifaces) {
|
||||||
for (String regex : ifaceRegexs) {
|
if (isRegexMatch(ifaceRegexs, s)) return true;
|
||||||
if (s.matches(regex)) {
|
}
|
||||||
return true;
|
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TetheringInterface getFirstMatchingTetheringInterface(final List<String> regexs,
|
||||||
|
final int type, final Set<TetheringInterface> ifaces) {
|
||||||
|
if (ifaces == null || regexs == null) return null;
|
||||||
|
|
||||||
|
final String[] regexArray = regexs.toArray(new String[0]);
|
||||||
|
for (TetheringInterface iface : ifaces) {
|
||||||
|
if (isRegexMatch(regexArray, iface.getInterface()) && type == iface.getType()) {
|
||||||
|
return iface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must poll the callback before looking at the member.
|
// Must poll the callback before looking at the member.
|
||||||
@@ -171,6 +188,8 @@ public final class CtsTetheringUtils {
|
|||||||
private TetheringInterfaceRegexps mTetherableRegex;
|
private TetheringInterfaceRegexps mTetherableRegex;
|
||||||
private List<String> mTetherableIfaces;
|
private List<String> mTetherableIfaces;
|
||||||
private List<String> mTetheredIfaces;
|
private List<String> mTetheredIfaces;
|
||||||
|
private String mErrorIface;
|
||||||
|
private int mErrorCode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTetheringSupported(boolean supported) {
|
public void onTetheringSupported(boolean supported) {
|
||||||
@@ -191,17 +210,41 @@ public final class CtsTetheringUtils {
|
|||||||
@Override
|
@Override
|
||||||
public void onTetherableInterfacesChanged(List<String> interfaces) {
|
public void onTetherableInterfacesChanged(List<String> interfaces) {
|
||||||
mTetherableIfaces = interfaces;
|
mTetherableIfaces = interfaces;
|
||||||
|
}
|
||||||
|
// Call the interface default implementation, which will call
|
||||||
|
// onTetherableInterfacesChanged(List<String>). This ensures that the default implementation
|
||||||
|
// of the new callback method calls the old callback method and avoids the need to convert
|
||||||
|
// Set<TetheringInterface> to List<String> in this code.
|
||||||
|
@Override
|
||||||
|
public void onTetherableInterfacesChanged(Set<TetheringInterface> interfaces) {
|
||||||
|
TetheringEventCallback.super.onTetherableInterfacesChanged(interfaces);
|
||||||
|
assertHasAllTetheringInterfaces(interfaces, mTetherableIfaces);
|
||||||
mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0));
|
mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTetheredInterfacesChanged(List<String> interfaces) {
|
public void onTetheredInterfacesChanged(List<String> interfaces) {
|
||||||
mTetheredIfaces = interfaces;
|
mTetheredIfaces = interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetheredInterfacesChanged(Set<TetheringInterface> interfaces) {
|
||||||
|
TetheringEventCallback.super.onTetheredInterfacesChanged(interfaces);
|
||||||
|
assertHasAllTetheringInterfaces(interfaces, mTetheredIfaces);
|
||||||
mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0));
|
mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(String ifName, int error) {
|
public void onError(String ifName, int error) {
|
||||||
|
mErrorIface = ifName;
|
||||||
|
mErrorCode = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(TetheringInterface ifName, int error) {
|
||||||
|
TetheringEventCallback.super.onError(ifName, error);
|
||||||
|
assertEquals(ifName.getInterface(), mErrorIface);
|
||||||
|
assertEquals(error, mErrorCode);
|
||||||
mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error));
|
mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,30 +258,66 @@ public final class CtsTetheringUtils {
|
|||||||
mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0));
|
mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectTetherableInterfacesChanged(@NonNull List<String> regexs) {
|
private void assertHasAllTetheringInterfaces(Set<TetheringInterface> tetheringIfaces,
|
||||||
|
List<String> ifaces) {
|
||||||
|
// This does not check that the interfaces are the same. This checks that the
|
||||||
|
// List<String> has all the interface names contained by the Set<TetheringInterface>.
|
||||||
|
assertEquals(tetheringIfaces.size(), ifaces.size());
|
||||||
|
for (TetheringInterface tether : tetheringIfaces) {
|
||||||
|
assertTrue("iface " + tether.getInterface()
|
||||||
|
+ " seen by new callback but not old callback",
|
||||||
|
ifaces.contains(tether.getInterface()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expectTetherableInterfacesChanged(@NonNull final List<String> regexs,
|
||||||
|
final int type) {
|
||||||
assertNotNull("No expected tetherable ifaces callback", mCurrent.poll(TIMEOUT_MS,
|
assertNotNull("No expected tetherable ifaces callback", mCurrent.poll(TIMEOUT_MS,
|
||||||
(cv) -> {
|
(cv) -> {
|
||||||
if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false;
|
if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false;
|
||||||
final List<String> interfaces = (List<String>) cv.callbackParam;
|
final Set<TetheringInterface> interfaces =
|
||||||
return isIfaceMatch(regexs, interfaces);
|
(Set<TetheringInterface>) cv.callbackParam;
|
||||||
|
return getFirstMatchingTetheringInterface(regexs, type, interfaces) != null;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectTetheredInterfacesChanged(@NonNull List<String> regexs) {
|
public void expectNoTetheringActive() {
|
||||||
assertNotNull("No expected tethered ifaces callback", mCurrent.poll(TIMEOUT_MS,
|
assertNotNull("At least one tethering type unexpectedly active",
|
||||||
(cv) -> {
|
mCurrent.poll(TIMEOUT_MS, (cv) -> {
|
||||||
if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false;
|
if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false;
|
||||||
|
|
||||||
final List<String> interfaces = (List<String>) cv.callbackParam;
|
return ((Set<TetheringInterface>) cv.callbackParam).isEmpty();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// Null regexs means no active tethering.
|
public TetheringInterface expectTetheredInterfacesChanged(
|
||||||
if (regexs == null) return interfaces.isEmpty();
|
@NonNull final List<String> regexs, final int type) {
|
||||||
|
while (true) {
|
||||||
|
final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
|
||||||
|
if (cv == null) {
|
||||||
|
fail("No expected tethered ifaces callback, expected type: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
return isIfaceMatch(regexs, interfaces);
|
if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue;
|
||||||
}));
|
|
||||||
|
final Set<TetheringInterface> interfaces =
|
||||||
|
(Set<TetheringInterface>) cv.callbackParam;
|
||||||
|
|
||||||
|
final TetheringInterface iface =
|
||||||
|
getFirstMatchingTetheringInterface(regexs, type, interfaces);
|
||||||
|
|
||||||
|
if (iface != null) return iface;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectCallbackStarted() {
|
public void expectCallbackStarted() {
|
||||||
|
// This method uses its own readhead because it just check whether last tethering status
|
||||||
|
// is updated after TetheringEventCallback get registered but do not check content
|
||||||
|
// of received callbacks. Using shared readhead (mCurrent) only when the callbacks the
|
||||||
|
// method polled is also not necessary for other methods which using shared readhead.
|
||||||
|
// All of methods using mCurrent is order mattered.
|
||||||
|
final ArrayTrackRecord<CallbackValue>.ReadHead history =
|
||||||
|
mHistory.newReadHead();
|
||||||
int receivedBitMap = 0;
|
int receivedBitMap = 0;
|
||||||
// The each bit represent a type from CallbackType.ON_*.
|
// The each bit represent a type from CallbackType.ON_*.
|
||||||
// Expect all of callbacks except for ON_ERROR.
|
// Expect all of callbacks except for ON_ERROR.
|
||||||
@@ -246,7 +325,7 @@ public final class CtsTetheringUtils {
|
|||||||
// Receive ON_ERROR on started callback is not matter. It just means tethering is
|
// Receive ON_ERROR on started callback is not matter. It just means tethering is
|
||||||
// failed last time, should able to continue the test this time.
|
// failed last time, should able to continue the test this time.
|
||||||
while ((receivedBitMap & expectedBitMap) != expectedBitMap) {
|
while ((receivedBitMap & expectedBitMap) != expectedBitMap) {
|
||||||
final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
|
final CallbackValue cv = history.poll(TIMEOUT_MS, c -> true);
|
||||||
if (cv == null) {
|
if (cv == null) {
|
||||||
fail("No expected callbacks, " + "expected bitmap: "
|
fail("No expected callbacks, " + "expected bitmap: "
|
||||||
+ expectedBitMap + ", actual: " + receivedBitMap);
|
+ expectedBitMap + ", actual: " + receivedBitMap);
|
||||||
@@ -269,14 +348,14 @@ public final class CtsTetheringUtils {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectErrorOrTethered(final String iface) {
|
public void expectErrorOrTethered(final TetheringInterface iface) {
|
||||||
assertNotNull("No expected callback", mCurrent.poll(TIMEOUT_MS, (cv) -> {
|
assertNotNull("No expected callback", mCurrent.poll(TIMEOUT_MS, (cv) -> {
|
||||||
if (cv.callbackType == CallbackType.ON_ERROR
|
if (cv.callbackType == CallbackType.ON_ERROR
|
||||||
&& iface.equals((String) cv.callbackParam)) {
|
&& iface.equals((TetheringInterface) cv.callbackParam)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (cv.callbackType == CallbackType.ON_TETHERED_IFACES
|
if (cv.callbackType == CallbackType.ON_TETHERED_IFACES
|
||||||
&& ((List<String>) cv.callbackParam).contains(iface)) {
|
&& ((Set<TetheringInterface>) cv.callbackParam).contains(iface)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,14 +407,6 @@ public final class CtsTetheringUtils {
|
|||||||
public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
|
public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
|
||||||
return mTetherableRegex;
|
return mTetherableRegex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getTetherableInterfaces() {
|
|
||||||
return mTetherableIfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getTetheredInterfaces() {
|
|
||||||
return mTetheredIfaces;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void waitForWifiEnabled(final Context ctx) throws Exception {
|
private static void waitForWifiEnabled(final Context ctx) throws Exception {
|
||||||
@@ -386,10 +457,9 @@ public final class CtsTetheringUtils {
|
|||||||
return !getWifiTetherableInterfaceRegexps(callback).isEmpty();
|
return !getWifiTetherableInterfaceRegexps(callback).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startWifiTethering(final TestTetheringEventCallback callback)
|
public TetheringInterface startWifiTethering(final TestTetheringEventCallback callback)
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
final List<String> wifiRegexs = getWifiTetherableInterfaceRegexps(callback);
|
final List<String> wifiRegexs = getWifiTetherableInterfaceRegexps(callback);
|
||||||
assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
|
|
||||||
|
|
||||||
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
|
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
|
||||||
final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
|
final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
|
||||||
@@ -397,11 +467,14 @@ public final class CtsTetheringUtils {
|
|||||||
mTm.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
|
mTm.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
|
||||||
startTetheringCallback.verifyTetheringStarted();
|
startTetheringCallback.verifyTetheringStarted();
|
||||||
|
|
||||||
callback.expectTetheredInterfacesChanged(wifiRegexs);
|
final TetheringInterface iface =
|
||||||
|
callback.expectTetheredInterfacesChanged(wifiRegexs, TETHERING_WIFI);
|
||||||
|
|
||||||
callback.expectOneOfOffloadStatusChanged(
|
callback.expectOneOfOffloadStatusChanged(
|
||||||
TETHER_HARDWARE_OFFLOAD_STARTED,
|
TETHER_HARDWARE_OFFLOAD_STARTED,
|
||||||
TETHER_HARDWARE_OFFLOAD_FAILED);
|
TETHER_HARDWARE_OFFLOAD_FAILED);
|
||||||
|
|
||||||
|
return iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StopSoftApCallback implements SoftApCallback {
|
private static class StopSoftApCallback implements SoftApCallback {
|
||||||
@@ -441,7 +514,7 @@ public final class CtsTetheringUtils {
|
|||||||
public void stopWifiTethering(final TestTetheringEventCallback callback) {
|
public void stopWifiTethering(final TestTetheringEventCallback callback) {
|
||||||
mTm.stopTethering(TETHERING_WIFI);
|
mTm.stopTethering(TETHERING_WIFI);
|
||||||
expectSoftApDisabled();
|
expectSoftApDisabled();
|
||||||
callback.expectTetheredInterfacesChanged(null);
|
callback.expectNoTetheringActive();
|
||||||
callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
|
callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
|||||||
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||||
import static android.net.cts.util.CtsTetheringUtils.isIfaceMatch;
|
import static android.net.cts.util.CtsTetheringUtils.isAnyIfaceMatch;
|
||||||
import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
@@ -48,6 +47,7 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
|
import android.net.TetheringInterface;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.TetheringManager.OnTetheringEntitlementResultListener;
|
import android.net.TetheringManager.OnTetheringEntitlementResultListener;
|
||||||
import android.net.TetheringManager.TetheringInterfaceRegexps;
|
import android.net.TetheringManager.TetheringInterfaceRegexps;
|
||||||
@@ -190,13 +190,13 @@ public class TetheringManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isIfaceActive(final String[] ifaceRegexs, final TetherState state) {
|
private boolean isIfaceActive(final String[] ifaceRegexs, final TetherState state) {
|
||||||
return isIfaceMatch(ifaceRegexs, state.mActive);
|
return isAnyIfaceMatch(ifaceRegexs, state.mActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNoErroredIfaces(final TetherState state, final String[] ifaceRegexs) {
|
private void assertNoErroredIfaces(final TetherState state, final String[] ifaceRegexs) {
|
||||||
if (state == null || state.mErrored == null) return;
|
if (state == null || state.mErrored == null) return;
|
||||||
|
|
||||||
if (isIfaceMatch(ifaceRegexs, state.mErrored)) {
|
if (isAnyIfaceMatch(ifaceRegexs, state.mErrored)) {
|
||||||
fail("Found failed tethering interfaces: " + Arrays.toString(state.mErrored.toArray()));
|
fail("Found failed tethering interfaces: " + Arrays.toString(state.mErrored.toArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,12 +256,13 @@ public class TetheringManagerTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
|
||||||
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
final TetheringInterface tetheredIface =
|
||||||
|
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
||||||
|
|
||||||
final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
|
assertNotNull(tetheredIface);
|
||||||
assertEquals(1, tetheredIfaces.size());
|
final String wifiTetheringIface = tetheredIface.getInterface();
|
||||||
final String wifiTetheringIface = tetheredIfaces.get(0);
|
|
||||||
|
|
||||||
mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
|
mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
|
||||||
|
|
||||||
@@ -272,7 +273,8 @@ public class TetheringManagerTest {
|
|||||||
if (ret == TETHER_ERROR_NO_ERROR) {
|
if (ret == TETHER_ERROR_NO_ERROR) {
|
||||||
// If calling #tether successful, there is a callback to tell the result of
|
// If calling #tether successful, there is a callback to tell the result of
|
||||||
// tethering setup.
|
// tethering setup.
|
||||||
tetherEventCallback.expectErrorOrTethered(wifiTetheringIface);
|
tetherEventCallback.expectErrorOrTethered(
|
||||||
|
new TetheringInterface(TETHERING_WIFI, wifiTetheringIface));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
mTM.untether(wifiTetheringIface);
|
mTM.untether(wifiTetheringIface);
|
||||||
@@ -319,7 +321,7 @@ public class TetheringManagerTest {
|
|||||||
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
|
||||||
|
|
||||||
mTM.stopAllTethering();
|
mTM.stopAllTethering();
|
||||||
tetherEventCallback.expectTetheredInterfacesChanged(null);
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
} finally {
|
} finally {
|
||||||
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
|
||||||
}
|
}
|
||||||
@@ -417,6 +419,7 @@ public class TetheringManagerTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
tetherEventCallback.assumeWifiTetheringSupported(mContext);
|
||||||
|
tetherEventCallback.expectNoTetheringActive();
|
||||||
|
|
||||||
previousWifiEnabledState = mWm.isWifiEnabled();
|
previousWifiEnabledState = mWm.isWifiEnabled();
|
||||||
if (previousWifiEnabledState) {
|
if (previousWifiEnabledState) {
|
||||||
|
|||||||
Reference in New Issue
Block a user