Merge "Fix EtherentTetheringTest flaky" into main am: 013425e27e

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2679555

Change-Id: If7328eb19a5783b92ae49f035ae4bd3d5f6199bb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Tethering/tests/integration/base/android/net/EthernetTetheringTestBase.java b/Tethering/tests/integration/base/android/net/EthernetTetheringTestBase.java
index 9dad301..83fc3e4 100644
--- a/Tethering/tests/integration/base/android/net/EthernetTetheringTestBase.java
+++ b/Tethering/tests/integration/base/android/net/EthernetTetheringTestBase.java
@@ -58,6 +58,8 @@
 import android.net.TetheringManager.TetheringRequest;
 import android.net.TetheringTester.TetheredDevice;
 import android.net.cts.util.CtsNetUtils;
+import android.net.cts.util.CtsTetheringUtils;
+import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.SystemClock;
@@ -75,6 +77,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
 
 import java.io.FileDescriptor;
 import java.net.Inet4Address;
@@ -161,6 +164,28 @@
     private TapPacketReader mDownstreamReader;
     private MyTetheringEventCallback mTetheringEventCallback;
 
+    @BeforeClass
+    public static void setUpOnce() throws Exception {
+        // The first test case may experience tethering restart with IP conflict handling.
+        // Tethering would cache the last upstreams so that the next enabled tethering avoids
+        // picking up the address that is in conflict with the upstreams. To protect subsequent
+        // tests, turn tethering on and off before running them.
+        final Context ctx = InstrumentationRegistry.getInstrumentation().getContext();
+        final CtsTetheringUtils utils = new CtsTetheringUtils(ctx);
+        final TestTetheringEventCallback callback = utils.registerTetheringEventCallback();
+        try {
+            if (!callback.isWifiTetheringSupported(ctx)) return;
+
+            callback.expectNoTetheringActive();
+
+            utils.startWifiTethering(callback);
+            callback.getCurrentValidUpstream();
+            utils.stopWifiTethering(callback);
+        } finally {
+            utils.unregisterTetheringEventCallback(callback);
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
         mHandlerThread = new HandlerThread(getClass().getSimpleName());
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 f506c23..dffd9d5 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
@@ -393,21 +393,28 @@
         }
 
         public void assumeTetheringSupported() {
+            assumeTrue(isTetheringSupported());
+        }
+
+        private boolean isTetheringSupported() {
             final ArrayTrackRecord<CallbackValue>.ReadHead history =
                     mHistory.newReadHead();
-            assertNotNull("No onSupported callback", history.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType != CallbackType.ON_SUPPORTED) return false;
+            final CallbackValue result = history.poll(TIMEOUT_MS, (cv) -> {
+                return cv.callbackType == CallbackType.ON_SUPPORTED;
+            });
 
-                assumeTrue(cv.callbackParam2 == 1 /* supported */);
-                return true;
-            }));
+            assertNotNull("No onSupported callback", result);
+            return result.callbackParam2 == 1 /* supported */;
         }
 
         public void assumeWifiTetheringSupported(final Context ctx) throws Exception {
-            assumeTetheringSupported();
+            assumeTrue(isWifiTetheringSupported(ctx));
+        }
 
-            assumeTrue(!getTetheringInterfaceRegexps().getTetherableWifiRegexs().isEmpty());
-            assumeTrue(isPortableHotspotSupported(ctx));
+        public boolean isWifiTetheringSupported(final Context ctx) throws Exception {
+            return isTetheringSupported()
+                    && !getTetheringInterfaceRegexps().getTetherableWifiRegexs().isEmpty()
+                    && isPortableHotspotSupported(ctx);
         }
 
         public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {