Only disable Wi-Fi IP serving on specific interface, if available

Test: as follows
    - built
    - flashed
    - booted
    - runtest frameworks-net passes
Bug: 32163131
Bug: 62343300

Merged-In: Id8d9c3f67f7a850af69069abee86adfc62841b28
Merged-In: Iac19359fd8712fa6a135f31bed9f0da97b3f2977
Merged-In: I99b170ebacc4135d1a09ce1ec3d43f76c6765de4
Change-Id: Ifd9131bad20810ee24c9436d8c0df7a81fae11d5
(cherry picked from commit 218c226b0882640a351deb0dd945a30b8bc32fff)
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index d6def4c..b6ea71e 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -792,30 +792,41 @@
                     case WifiManager.WIFI_AP_STATE_DISABLING:
                     case WifiManager.WIFI_AP_STATE_FAILED:
                     default:
-                        disableWifiIpServingLocked(curState);
+                        disableWifiIpServingLocked(ifname, curState);
                         break;
                 }
             }
         }
     }
 
-    // TODO: Pass in the interface name and, if non-empty, only turn down IP
-    // serving on that one interface.
-    private void disableWifiIpServingLocked(int apState) {
-        if (DBG) Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" + apState);
+    private void disableWifiIpServingLocked(String ifname, int apState) {
+        mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
 
-        // Tell appropriate interface state machines that they should tear
-        // themselves down.
+        // 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.
+        // TODO: Remove this altogether, once Wi-Fi reliably gives us an
+        // interface name with every broadcast.
+        mWifiTetherRequested = false;
+
+        if (!TextUtils.isEmpty(ifname)) {
+            final TetherState ts = mTetherStates.get(ifname);
+            if (ts != null) {
+                ts.stateMachine.unwanted();
+                return;
+            }
+        }
+
         for (int i = 0; i < mTetherStates.size(); i++) {
             TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine;
             if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
-                tism.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
-                break;  // There should be at most one of these.
+                tism.unwanted();
+                return;
             }
         }
-        // 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;
+
+        mLog.log("Error disabling Wi-Fi IP serving; " +
+                (TextUtils.isEmpty(ifname) ? "no interface name specified"
+                                           : "specified interface: " + ifname));
     }
 
     private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 4a1d405..ffd71ca 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -127,6 +127,10 @@
 
     public int lastError() { return mLastError; }
 
+    public void stop() { sendMessage(CMD_INTERFACE_DOWN); }
+
+    public void unwanted() { sendMessage(CMD_TETHER_UNREQUESTED); }
+
     // configured when we start tethering and unconfig'd on error or conclusion
     private boolean configureIfaceIp(boolean enabled) {
         if (VDBG) Log.d(TAG, "configureIfaceIp(" + enabled + ")");