SyncSM8.2: make IpServer support syncSM

After this change, IpServer could switch to use syncSM.

Test: atest TetheringTests
Change-Id: I2d7fa47cd020f3e76e7a8beaefb98852e93545f8
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index c04d0dc..930469b 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -511,8 +511,12 @@
 
         private void handleError() {
             mLastError = TETHER_ERROR_DHCPSERVER_ERROR;
-            sendMessageAtFrontOfQueueToAsyncSM(CMD_SERVICE_FAILED_TO_START,
-                    TETHER_ERROR_DHCPSERVER_ERROR);
+            if (USE_SYNC_SM) {
+                sendMessage(CMD_SERVICE_FAILED_TO_START, TETHER_ERROR_DHCPSERVER_ERROR);
+            } else {
+                sendMessageAtFrontOfQueueToAsyncSM(CMD_SERVICE_FAILED_TO_START,
+                        TETHER_ERROR_DHCPSERVER_ERROR);
+            }
         }
     }
 
@@ -1128,8 +1132,13 @@
                 // message (and generally ignores them). It is difficult to know for sure whether
                 // this is correct in all cases, but this is equivalent to what IpServer was doing
                 // in previous versions of the mainline module.
-                // TODO : remove this after migrating to the Sync StateMachine.
-                sendMessageAtFrontOfQueueToAsyncSM(CMD_SERVICE_FAILED_TO_START, mLastError);
+                // TODO : remove sendMessageAtFrontOfQueueToAsyncSM after migrating to the Sync
+                // StateMachine.
+                if (USE_SYNC_SM) {
+                    sendSelfMessageToSyncSM(CMD_SERVICE_FAILED_TO_START, mLastError);
+                } else {
+                    sendMessageAtFrontOfQueueToAsyncSM(CMD_SERVICE_FAILED_TO_START, mLastError);
+                }
             }
 
             if (DBG) Log.d(TAG, getStateString(mDesiredInterfaceState) + " serve " + mIfaceName);
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index d945025..ebf443b 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -214,8 +214,8 @@
 
     @Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
 
-    private final TestLooper mLooper = new TestLooper();
-    private final Handler mHandler = new Handler(mLooper.getLooper());
+    private TestLooper mLooper;
+    private Handler mHandler;
     private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor =
             ArgumentCaptor.forClass(LinkProperties.class);
     private IpServer mIpServer;
@@ -252,12 +252,7 @@
         when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(usingBpfOffload);
         when(mTetherConfig.useLegacyDhcpServer()).thenReturn(usingLegacyDhcp);
         when(mTetherConfig.getP2pLeasesSubnetPrefixLength()).thenReturn(P2P_SUBNET_PREFIX_LENGTH);
-        // Recreate mBpfCoordinator again here because mTetherConfig has changed
-        mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
-        mIpServer = new IpServer(
-                IFACE_NAME, mHandler, interfaceType, mSharedLog, mNetd, mBpfCoordinator,
-                mRoutingCoordinatorManager, mCallback, mTetherConfig, mAddressCoordinator,
-                mTetheringMetrics, mDependencies);
+        mIpServer = createIpServer(interfaceType);
         mIpServer.start();
         mNeighborEventConsumer = neighborCaptor.getValue();
 
@@ -322,6 +317,13 @@
         when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(DEFAULT_USING_BPF_OFFLOAD);
         when(mTetherConfig.useLegacyDhcpServer()).thenReturn(false /* default value */);
 
+        setUpDhcpServer();
+    }
+
+    // In order to interact with syncSM from the test, IpServer must be created in test thread.
+    private IpServer createIpServer(final int interfaceType) {
+        mLooper = new TestLooper();
+        mHandler = new Handler(mLooper.getLooper());
         mBpfDeps = new BpfCoordinator.Dependencies() {
                     @NonNull
                     public Handler getHandler() {
@@ -394,18 +396,19 @@
                         return mBpfErrorMap;
                     }
                 };
-        mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
 
-        setUpDhcpServer();
+        mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
+        return new IpServer(IFACE_NAME, mHandler, interfaceType, mSharedLog, mNetd, mBpfCoordinator,
+                mRoutingCoordinatorManager, mCallback, mTetherConfig, mAddressCoordinator,
+                mTetheringMetrics, mDependencies);
+
     }
 
     @Test
-    public void startsOutAvailable() {
+    public void startsOutAvailable() throws Exception {
         when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
                 .thenReturn(mIpNeighborMonitor);
-        mIpServer = new IpServer(IFACE_NAME, mHandler, TETHERING_BLUETOOTH, mSharedLog,
-                mNetd, mBpfCoordinator, mRoutingCoordinatorManager, mCallback, mTetherConfig,
-                mAddressCoordinator, mTetheringMetrics, mDependencies);
+        mIpServer = createIpServer(TETHERING_BLUETOOTH);
         mIpServer.start();
         mLooper.dispatchAll();
         verify(mCallback).updateInterfaceState(
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index f89ee8e..6eba590 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -302,7 +302,7 @@
     // Like so many Android system APIs, these cannot be mocked because it is marked final.
     // We have to use the real versions.
     private final PersistableBundle mCarrierConfig = new PersistableBundle();
-    private final TestLooper mLooper = new TestLooper();
+    private TestLooper mLooper;
 
     private Vector<Intent> mIntents;
     private BroadcastInterceptingContext mServiceContext;
@@ -680,7 +680,14 @@
 
         mCm = spy(new TestConnectivityManager(mServiceContext, mock(IConnectivityManager.class)));
 
-        mTethering = makeTethering();
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
+    }
+
+    // In order to interact with syncSM from the test, tethering must be created in test thread.
+    private void initTetheringOnTestThread() throws Exception {
+        mLooper = new TestLooper();
+        mTethering = new Tethering(mTetheringDependencies);
         verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
         verify(mNetd).registerUnsolicitedEventListener(any());
         verifyDefaultNetworkRequestFiled();
@@ -704,9 +711,6 @@
                     localOnlyCallbackCaptor.capture());
             mLocalOnlyHotspotCallback = localOnlyCallbackCaptor.getValue();
         }
-
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
     }
 
     private void setTetheringSupported(final boolean supported) {
@@ -738,10 +742,6 @@
         doReturn(upstreamState).when(mUpstreamNetworkMonitor).selectPreferredUpstreamType(any());
     }
 
-    private Tethering makeTethering() {
-        return new Tethering(mTetheringDependencies);
-    }
-
     private TetheringRequestParcel createTetheringRequestParcel(final int type) {
         return createTetheringRequestParcel(type, null, null, false, CONNECTIVITY_SCOPE_GLOBAL);
     }
@@ -885,6 +885,7 @@
 
     public void failingLocalOnlyHotspotLegacyApBroadcast(
             boolean emulateInterfaceStatusChanged) throws Exception {
+        initTetheringOnTestThread();
         // Emulate externally-visible WifiManager effects, causing the
         // per-interface state machine to start up, and telling us that
         // hotspot mode is to be started.
@@ -936,6 +937,7 @@
 
     @Test
     public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
+        initTetheringOnTestThread();
         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         initTetheringUpstream(upstreamState);
         prepareUsbTethering();
@@ -1012,6 +1014,7 @@
 
     public void workingLocalOnlyHotspotEnrichedApBroadcast(
             boolean emulateInterfaceStatusChanged) throws Exception {
+        initTetheringOnTestThread();
         // Emulate externally-visible WifiManager effects, causing the
         // per-interface state machine to start up, and telling us that
         // hotspot mode is to be started.
@@ -1075,6 +1078,7 @@
 
     @Test
     public void workingMobileUsbTethering_IPv4() throws Exception {
+        initTetheringOnTestThread();
         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         runUsbTethering(upstreamState);
 
@@ -1089,7 +1093,8 @@
     }
 
     @Test
-    public void workingMobileUsbTethering_IPv4LegacyDhcp() {
+    public void workingMobileUsbTethering_IPv4LegacyDhcp() throws Exception {
+        initTetheringOnTestThread();
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 true);
         sendConfigurationChanged();
@@ -1102,6 +1107,7 @@
 
     @Test
     public void workingMobileUsbTethering_IPv6() throws Exception {
+        initTetheringOnTestThread();
         UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
         runUsbTethering(upstreamState);
 
@@ -1117,6 +1123,7 @@
 
     @Test
     public void workingMobileUsbTethering_DualStack() throws Exception {
+        initTetheringOnTestThread();
         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
         runUsbTethering(upstreamState);
 
@@ -1134,6 +1141,7 @@
 
     @Test
     public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
+        initTetheringOnTestThread();
         UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
         runUsbTethering(upstreamState);
 
@@ -1153,6 +1161,7 @@
 
     @Test
     public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
+        initTetheringOnTestThread();
         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
@@ -1194,6 +1203,7 @@
 
     @Test
     public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
+        initTetheringOnTestThread();
         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
         sendConfigurationChanged();
 
@@ -1242,6 +1252,7 @@
     }
 
     private void verifyAutomaticUpstreamSelection(boolean configAutomatic) throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
@@ -1341,6 +1352,7 @@
     @Test
     @IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
     public void testLegacyUpstreamSelection() throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
@@ -1491,6 +1503,7 @@
     // +-------+-------+-------+-------+-------+
     //
     private void verifyChooseDunUpstreamByAutomaticMode(boolean configAutomatic) throws Exception {
+        initTetheringOnTestThread();
         // Enable automatic upstream selection.
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
@@ -1551,6 +1564,7 @@
     //
     @Test
     public void testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi() throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
@@ -1602,6 +1616,7 @@
     //
     @Test
     public void testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi() throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
@@ -1643,6 +1658,7 @@
     //
     @Test
     public void testChooseDunUpstreamByAutomaticMode_defaultNetworkCell() throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
@@ -1687,6 +1703,7 @@
     //
     @Test
     public void testChooseDunUpstreamByAutomaticMode_loseAndRegainDun() throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
         setupDunUpstreamTest(true /* configAutomatic */, inOrder);
@@ -1728,6 +1745,7 @@
     @Test
     public void testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell()
             throws Exception {
+        initTetheringOnTestThread();
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
@@ -1765,6 +1783,7 @@
     @Test
     @IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
     public void testChooseDunUpstreamByLegacyMode() throws Exception {
+        initTetheringOnTestThread();
         // Enable Legacy upstream selection.
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
@@ -1857,6 +1876,7 @@
 
     @Test
     public void workingNcmTethering() throws Exception {
+        initTetheringOnTestThread();
         runNcmTethering();
 
         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
@@ -1864,7 +1884,8 @@
     }
 
     @Test
-    public void workingNcmTethering_LegacyDhcp() {
+    public void workingNcmTethering_LegacyDhcp() throws Exception {
+        initTetheringOnTestThread();
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 true);
         sendConfigurationChanged();
@@ -1886,6 +1907,7 @@
     // TODO: Test with and without interfaceStatusChanged().
     @Test
     public void failingWifiTetheringLegacyApBroadcast() throws Exception {
+        initTetheringOnTestThread();
         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
@@ -1914,6 +1936,7 @@
     // TODO: Test with and without interfaceStatusChanged().
     @Test
     public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
+        initTetheringOnTestThread();
         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
@@ -1962,6 +1985,7 @@
     // TODO: Test with and without interfaceStatusChanged().
     @Test
     public void failureEnablingIpForwarding() throws Exception {
+        initTetheringOnTestThread();
         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
         doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
 
@@ -2109,7 +2133,8 @@
     }
 
     @Test
-    public void testUntetherUsbWhenRestrictionIsOn() {
+    public void testUntetherUsbWhenRestrictionIsOn() throws Exception {
+        initTetheringOnTestThread();
         // Start usb tethering and check that usb interface is tethered.
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         runUsbTethering(upstreamState);
@@ -2286,6 +2311,7 @@
 
     @Test
     public void testRegisterTetheringEventCallback() throws Exception {
+        initTetheringOnTestThread();
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
         TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
         final TetheringInterface wifiIface = new TetheringInterface(
@@ -2350,6 +2376,7 @@
 
     @Test
     public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
+        initTetheringOnTestThread();
         final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
         mTethering.registerTetheringEventCallback(callback);
@@ -2389,6 +2416,7 @@
 
     @Test
     public void testMultiSimAware() throws Exception {
+        initTetheringOnTestThread();
         final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
         assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
 
@@ -2401,6 +2429,7 @@
 
     @Test
     public void testNoDuplicatedEthernetRequest() throws Exception {
+        initTetheringOnTestThread();
         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
         mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), TEST_CALLER_PKG,
@@ -2421,6 +2450,7 @@
 
     private void workingWifiP2pGroupOwner(
             boolean emulateInterfaceStatusChanged) throws Exception {
+        initTetheringOnTestThread();
         if (emulateInterfaceStatusChanged) {
             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
         }
@@ -2460,6 +2490,7 @@
 
     private void workingWifiP2pGroupClient(
             boolean emulateInterfaceStatusChanged) throws Exception {
+        initTetheringOnTestThread();
         if (emulateInterfaceStatusChanged) {
             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
         }
@@ -2500,6 +2531,7 @@
 
     private void workingWifiP2pGroupOwnerLegacyMode(
             boolean emulateInterfaceStatusChanged) throws Exception {
+        initTetheringOnTestThread();
         // change to legacy mode and update tethering information by chaning SIM
         when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
                 .thenReturn(new String[]{});
@@ -2549,7 +2581,8 @@
     }
 
     @Test
-    public void testDataSaverChanged() {
+    public void testDataSaverChanged() throws Exception {
+        initTetheringOnTestThread();
         // Start Tethering.
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
         runUsbTethering(upstreamState);
@@ -2604,6 +2637,7 @@
 
     @Test
     public void testMultipleStartTethering() throws Exception {
+        initTetheringOnTestThread();
         final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
         final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
         final String serverAddr = "192.168.20.1";
@@ -2647,6 +2681,7 @@
 
     @Test
     public void testRequestStaticIp() throws Exception {
+        initTetheringOnTestThread();
         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
@@ -2676,7 +2711,8 @@
     }
 
     @Test
-    public void testUpstreamNetworkChanged() {
+    public void testUpstreamNetworkChanged() throws Exception {
+        initTetheringOnTestThread();
         final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
                 mTetheringDependencies.mUpstreamNetworkMonitorSM;
         final InOrder inOrder = inOrder(mNotificationUpdater);
@@ -2718,7 +2754,8 @@
     }
 
     @Test
-    public void testUpstreamCapabilitiesChanged() {
+    public void testUpstreamCapabilitiesChanged() throws Exception {
+        initTetheringOnTestThread();
         final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
                 mTetheringDependencies.mUpstreamNetworkMonitorSM;
         final InOrder inOrder = inOrder(mNotificationUpdater);
@@ -2753,6 +2790,7 @@
 
     @Test
     public void testUpstreamCapabilitiesChanged_startStopTethering() throws Exception {
+        initTetheringOnTestThread();
         final TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
 
         // Start USB tethering with no current upstream.
@@ -2774,6 +2812,7 @@
 
     @Test
     public void testDumpTetheringLog() throws Exception {
+        initTetheringOnTestThread();
         final FileDescriptor mockFd = mock(FileDescriptor.class);
         final PrintWriter mockPw = mock(PrintWriter.class);
         runUsbTethering(null);
@@ -2787,6 +2826,7 @@
 
     @Test
     public void testExemptFromEntitlementCheck() throws Exception {
+        initTetheringOnTestThread();
         setupForRequiredProvisioning();
         final TetheringRequestParcel wifiNotExemptRequest =
                 createTetheringRequestParcel(TETHERING_WIFI, null, null, false,
@@ -2877,6 +2917,7 @@
 
     @Test
     public void testHandleIpConflict() throws Exception {
+        initTetheringOnTestThread();
         final Network wifiNetwork = new Network(200);
         final Network[] allNetworks = { wifiNetwork };
         doReturn(allNetworks).when(mCm).getAllNetworks();
@@ -2911,6 +2952,7 @@
 
     @Test
     public void testNoAddressAvailable() throws Exception {
+        initTetheringOnTestThread();
         final Network wifiNetwork = new Network(200);
         final Network btNetwork = new Network(201);
         final Network mobileNetwork = new Network(202);
@@ -2972,6 +3014,7 @@
 
     @Test
     public void testProvisioningNeededButUnavailable() throws Exception {
+        initTetheringOnTestThread();
         assertTrue(mTethering.isTetheringSupported());
         verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
 
@@ -2989,6 +3032,7 @@
 
     @Test
     public void testUpdateConnectedClients() throws Exception {
+        initTetheringOnTestThread();
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
         runAsShell(NETWORK_SETTINGS, () -> {
             mTethering.registerTetheringEventCallback(callback);
@@ -3038,6 +3082,7 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
     public void testUpdateConnectedClientsForLocalOnlyHotspot() throws Exception {
+        initTetheringOnTestThread();
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
         runAsShell(NETWORK_SETTINGS, () -> {
             mTethering.registerTetheringEventCallback(callback);
@@ -3070,6 +3115,7 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
     public void testConnectedClientsForSapAndLohsConcurrency() throws Exception {
+        initTetheringOnTestThread();
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
         runAsShell(NETWORK_SETTINGS, () -> {
             mTethering.registerTetheringEventCallback(callback);
@@ -3195,6 +3241,7 @@
 
     @Test
     public void testBluetoothTethering() throws Exception {
+        initTetheringOnTestThread();
         // Switch to @IgnoreUpTo(Build.VERSION_CODES.S_V2) when it is available for AOSP.
         assumeTrue(isAtLeastT());
 
@@ -3231,6 +3278,7 @@
 
     @Test
     public void testBluetoothTetheringBeforeT() throws Exception {
+        initTetheringOnTestThread();
         // Switch to @IgnoreAfter(Build.VERSION_CODES.S_V2) when it is available for AOSP.
         assumeFalse(isAtLeastT());
 
@@ -3278,6 +3326,7 @@
 
     @Test
     public void testBluetoothServiceDisconnects() throws Exception {
+        initTetheringOnTestThread();
         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH),
@@ -3432,6 +3481,7 @@
 
     @Test
     public void testUsbFunctionConfigurationChange() throws Exception {
+        initTetheringOnTestThread();
         // Run TETHERING_NCM.
         runNcmTethering();
         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
@@ -3490,6 +3540,7 @@
 
     @Test
     public void testTetheringSupported() throws Exception {
+        initTetheringOnTestThread();
         final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes();
         // Check tethering is supported after initialization.
         TestTetheringEventCallback callback = new TestTetheringEventCallback();
@@ -3562,6 +3613,7 @@
 
     @Test
     public void testIpv4AddressForSapAndLohsConcurrency() throws Exception {
+        initTetheringOnTestThread();
         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);