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
diff --git a/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java b/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
index 85ee466..dd2ff9e 100644
--- a/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
+++ b/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
@@ -56,6 +56,7 @@
 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 @@
             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);
 
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
index d5e9c9e..8b904bc 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
@@ -52,6 +52,7 @@
 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 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 @@
             }
         }
 
+        @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