Properly disable WiFi tethering

When Tethering.stopTethering(<wifi>) 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)
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6f67b6f..e9b6690 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 @@
 
     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 @@
                 }
             } 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 @@
                             // 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 @@
                                 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;
                     }
                 }