diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index eedd09f3ba9b4..316cfad187732 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -868,23 +868,16 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering ipServingMode = IControlsTethering.STATE_LOCAL_ONLY; break; default: - // Resort to legacy "guessing" behaviour. - // - // When the AP comes up and we've been requested to tether it, - // do so. Otherwise, assume it's a local-only hotspot request. - // - // TODO: Once all AP broadcasts are known to include ifname and - // mode information delete this code path and log an error. - ipServingMode = mWifiTetherRequested - ? IControlsTethering.STATE_TETHERED - : IControlsTethering.STATE_LOCAL_ONLY; - break; + mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode); + return; } if (!TextUtils.isEmpty(ifname)) { changeInterfaceState(ifname, ipServingMode); } else { - tetherMatchingInterfaces(ipServingMode, ConnectivityManager.TETHERING_WIFI); + mLog.e(String.format( + "Cannot enable IP serving in mode %s on missing interface name", + ipServingMode)); } } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java index 651de8910925d..b7fbfb756b1d0 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -79,6 +79,9 @@ public class TetheringConfiguration { tetherableUsbRegexs = ctx.getResources().getStringArray( com.android.internal.R.array.config_tether_usb_regexs); + // TODO: Evaluate deleting this altogether now that Wi-Fi always passes + // us an interface name. Careful consideration needs to be given to + // implications for Settings and for provisioning checks. tetherableWifiRegexs = ctx.getResources().getStringArray( com.android.internal.R.array.config_tether_wifi_regexs); tetherableBluetoothRegexs = ctx.getResources().getStringArray( diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index be0924aa4f93b..2137e557cd0cf 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -245,10 +245,7 @@ public class TetheringTest { mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception { - if (!ifnameKnown) { - verify(mNMService, times(1)).listInterfaces(); - } + private void verifyInterfaceServingModeStarted() throws Exception { verify(mNMService, times(1)).getInterfaceConfig(mTestIfname); verify(mNMService, times(1)) .setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class)); @@ -264,21 +261,36 @@ public class TetheringTest { mIntents.remove(bcast); } - public void workingLocalOnlyHotspot(boolean enrichedApBroadcast) throws Exception { + @Test + public void failingLocalOnlyHotspotLegacyApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); // Emulate externally-visible WifiManager effects, causing the // per-interface state machine to start up, and telling us that // hotspot mode is to be started. mTethering.interfaceStatusChanged(mTestIfname, true); - if (enrichedApBroadcast) { - sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY); - } else { - sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); - } + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); mLooper.dispatchAll(); - verifyInterfaceServingModeStarted(enrichedApBroadcast); + verify(mConnectivityManager, atLeastOnce()).isTetheringSupported(); + verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); + verifyNoMoreInteractions(mConnectivityManager); + verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mWifiManager); + } + + @Test + public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception { + when(mConnectivityManager.isTetheringSupported()).thenReturn(true); + + // Emulate externally-visible WifiManager effects, causing the + // per-interface state machine to start up, and telling us that + // hotspot mode is to be started. + mTethering.interfaceStatusChanged(mTestIfname, true); + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY); + mLooper.dispatchAll(); + + verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); @@ -319,16 +331,7 @@ public class TetheringTest { } @Test - public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception { - workingLocalOnlyHotspot(false); - } - - @Test - public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception { - workingLocalOnlyHotspot(true); - } - - public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception { + public void failingWifiTetheringLegacyApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); @@ -344,14 +347,37 @@ public class TetheringTest { // per-interface state machine to start up, and telling us that // tethering mode is to be started. mTethering.interfaceStatusChanged(mTestIfname, true); - if (enrichedApBroadcast) { - sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED); - } else { - sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); - } + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); mLooper.dispatchAll(); - verifyInterfaceServingModeStarted(enrichedApBroadcast); + verify(mConnectivityManager, atLeastOnce()).isTetheringSupported(); + verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); + verifyNoMoreInteractions(mConnectivityManager); + verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mWifiManager); + } + + @Test + public void workingWifiTetheringEnrichedApBroadcast() throws Exception { + when(mConnectivityManager.isTetheringSupported()).thenReturn(true); + when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); + + // Emulate pressing the WiFi tethering button. + mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false); + mLooper.dispatchAll(); + verify(mWifiManager, times(1)).startSoftAp(null); + verifyNoMoreInteractions(mWifiManager); + verifyNoMoreInteractions(mConnectivityManager); + verifyNoMoreInteractions(mNMService); + + // Emulate externally-visible WifiManager effects, causing the + // per-interface state machine to start up, and telling us that + // tethering mode is to be started. + mTethering.interfaceStatusChanged(mTestIfname, true); + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED); + mLooper.dispatchAll(); + + verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); @@ -411,16 +437,6 @@ public class TetheringTest { mTethering.getLastTetherError(mTestIfname)); } - @Test - public void workingWifiTetheringLegacyApBroadcast() throws Exception { - workingWifiTethering(false); - } - - @Test - public void workingWifiTetheringEnrichedApBroadcast() throws Exception { - workingWifiTethering(true); - } - @Test public void failureEnablingIpForwarding() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); @@ -439,11 +455,9 @@ public class TetheringTest { // per-interface state machine to start up, and telling us that // tethering mode is to be started. mTethering.interfaceStatusChanged(mTestIfname, true); - sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED); + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); - // Activity caused by test_wlan0 becoming available. - verify(mNMService, times(1)).listInterfaces(); // We verify get/set called twice here: once for setup and once during // teardown because all events happen over the course of the single // dispatchAll() above.