Manual start tethering if it doesn't restart automatically

Because of race condition inside tethering module, restart tethering is
not reliable when address conflict. Manual start it for testing if it
doesn't restart automatically.

Bug: 176048959
Bug: 240878641
Bug: 178560045
Bug: 178116595

Test: atest MtsTetheringTestLatestSdk
Change-Id: Id1473b968cd20afde70bca1903114df6f0b510a8
This commit is contained in:
Mark 2022-08-10 08:28:22 +00:00 • committed by Mark Chien
commit b8d1afd408
2 changed files with 34 additions and 8 deletions

View file

@ -56,6 +56,7 @@ import java.util.List;
public class TetheringModuleTest {
private Context mContext;
private CtsTetheringUtils mCtsTetheringUtils;
private final long mRestartTimeOutMs = 5_000;
@Before
public void setUp() throws Exception {
@ -103,8 +104,20 @@ public class TetheringModuleTest {
final List<String> wifiRegexs =
tetherEventCallback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs, TETHERING_WIFI);
nif = NetworkInterface.getByName(wifiTetheringIface);
final TetheringInterface restartedIface =
tetherEventCallback.pollTetheredInterfacesChanged(wifiRegexs, TETHERING_WIFI,
mRestartTimeOutMs);
final TetheringInterface newIface;
if (restartedIface != null) {
newIface = restartedIface;
} else {
// Because of race inside tethering module, there is no guarantee wifi tethering
// would restart successfully. If tethering don't auto restarted, restarting it
// manually. TODO(b/242649651): remove this when tethering auto restart is reliable.
newIface = mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
}
nif = NetworkInterface.getByName(newIface.getInterface());
final LinkAddress newHotspotAddr = getFirstIpv4Address(nif);
assertNotNull(newHotspotAddr);

View file

@ -52,6 +52,7 @@ import android.net.wifi.WifiManager.SoftApCallback;
import android.os.ConditionVariable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.compatibility.common.util.SystemUtil;
import com.android.net.module.util.ArrayTrackRecord;
@ -296,13 +297,12 @@ public final class CtsTetheringUtils {
}));
}
public TetheringInterface expectTetheredInterfacesChanged(
@NonNull final List<String> regexs, final int type) {
@Nullable
public TetheringInterface pollTetheredInterfacesChanged(
@NonNull final List<String> regexs, final int type, long timeOutMs) {
while (true) {
final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
if (cv == null) {
fail("No expected tethered ifaces callback, expected type: " + type);
}
final CallbackValue cv = mCurrent.poll(timeOutMs, c -> true);
if (cv == null) return null;
if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue;
@ -316,6 +316,19 @@ public final class CtsTetheringUtils {
}
}
@NonNull
public TetheringInterface expectTetheredInterfacesChanged(
@NonNull final List<String> regexs, final int type) {
final TetheringInterface iface = pollTetheredInterfacesChanged(regexs, type,
TIMEOUT_MS);
if (iface == null) {
fail("No expected tethered ifaces callback, expected type: " + type);
}
return iface;
}
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