From 05f86d1eec26b588caf45dbfb5a412176428e0a7 Mon Sep 17 00:00:00 2001 From: Christopher Wiley Date: Wed, 13 Jul 2016 18:57:34 -0700 Subject: [PATCH] Properly disable WiFi tethering When Tethering.stopTethering() is called, we set mWifiTetheringRequested to false and request the AP be torn down. Previously, we would discard WIFI_AP_STATE_CHANGED_ACTION Intents, because mWifiTetheringRequested was set to false. This would in turn cause us to leave tethering enabled, because we only tear down tethering upon noticing that the interface is going down (as signalled by WifiManager via this Intent). In the past, this was covered up because we would tear down tethering when the interface was taken down. Now that we rely on SoftApManager to notify us of AP state, we need to pay very close attention to what is being said about the state. Bug: 30124308 Test: Can toggle tethering on and off reliably on shamu, bullhead, angler with no SIM. Change-Id: If46a8ee11cf4c07c5cc336523f5e5f00273500ec (cherry picked from commit e52b24a0c52c6e29ea99760c920724f4143ac605) --- .../server/connectivity/Tethering.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 6f67b6fae8fc8..e9b66902d4916 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -449,8 +449,6 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering private int setWifiTethering(final boolean enable) { synchronized (mPublicSync) { - // Note that we're maintaining a predicate that mWifiTetherRequested always matches - // our last request to WifiManager re: its AP enabled status. mWifiTetherRequested = enable; final WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); @@ -793,10 +791,6 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { synchronized (Tethering.this.mPublicSync) { - if (!mWifiTetherRequested) { - // We only care when we're trying to tether via our WiFi interface. - return; - } int curState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_DISABLED); switch (curState) { @@ -804,8 +798,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering // We can see this state on the way to both enabled and failure states. break; case WifiManager.WIFI_AP_STATE_ENABLED: - // Tell an appropriate interface state machine that it should tether. - tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_WIFI); + // When the AP comes up and we've been requested to tether it, do so. + if (mWifiTetherRequested) { + tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_WIFI); + } break; case WifiManager.WIFI_AP_STATE_DISABLED: case WifiManager.WIFI_AP_STATE_DISABLING: @@ -815,10 +811,20 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" + curState); } - // Tell an appropriate interface state machine that - // it needs to tear itself down. - tetherMatchingInterfaces(false, ConnectivityManager.TETHERING_WIFI); - setWifiTethering(false); + // Tell appropriate interface state machines that they should tear + // themselves down. + for (int i = 0; i < mTetherStates.size(); i++) { + TetherInterfaceStateMachine tism = + mTetherStates.valueAt(i).mStateMachine; + if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) { + tism.sendMessage( + TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); + break; // There should be at most one of these. + } + } + // Regardless of whether we requested this transition, the AP has gone + // down. Don't try to tether again unless we're requested to do so. + mWifiTetherRequested = false; break; } }