Loading services/core/java/com/android/server/connectivity/Tethering.java +5 −12 Original line number Diff line number Diff line Loading @@ -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)); } } Loading services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +3 −0 Original line number Diff line number Diff line Loading @@ -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( Loading tests/net/java/com/android/server/connectivity/TetheringTest.java +51 −37 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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); mLooper.dispatchAll(); 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(enrichedApBroadcast); verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); Loading Loading @@ -319,16 +331,34 @@ public class TetheringTest { } @Test public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception { workingLocalOnlyHotspot(false); } public void failingWifiTetheringLegacyApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); @Test public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception { workingLocalOnlyHotspot(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); mLooper.dispatchAll(); verify(mConnectivityManager, atLeastOnce()).isTetheringSupported(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verifyNoMoreInteractions(mConnectivityManager); verifyNoMoreInteractions(mNMService); verifyNoMoreInteractions(mWifiManager); } public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception { @Test public void workingWifiTetheringEnrichedApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); Loading @@ -344,14 +374,10 @@ 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); } mLooper.dispatchAll(); verifyInterfaceServingModeStarted(enrichedApBroadcast); verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); Loading Loading @@ -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); Loading @@ -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. Loading Loading
services/core/java/com/android/server/connectivity/Tethering.java +5 −12 Original line number Diff line number Diff line Loading @@ -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)); } } Loading
services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +3 −0 Original line number Diff line number Diff line Loading @@ -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( Loading
tests/net/java/com/android/server/connectivity/TetheringTest.java +51 −37 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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); mLooper.dispatchAll(); 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(enrichedApBroadcast); verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); Loading Loading @@ -319,16 +331,34 @@ public class TetheringTest { } @Test public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception { workingLocalOnlyHotspot(false); } public void failingWifiTetheringLegacyApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); @Test public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception { workingLocalOnlyHotspot(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); mLooper.dispatchAll(); verify(mConnectivityManager, atLeastOnce()).isTetheringSupported(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verifyNoMoreInteractions(mConnectivityManager); verifyNoMoreInteractions(mNMService); verifyNoMoreInteractions(mWifiManager); } public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception { @Test public void workingWifiTetheringEnrichedApBroadcast() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); Loading @@ -344,14 +374,10 @@ 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); } mLooper.dispatchAll(); verifyInterfaceServingModeStarted(enrichedApBroadcast); verifyInterfaceServingModeStarted(); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); Loading Loading @@ -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); Loading @@ -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. Loading