Remove all knowledge of tethering from SoftApManager

This logic has moved into Tethering and TetherInterfaceStatemachine,
where it probably always belonged.

Bug: 29054780
Test: WiFi tethering continues to work on angler
      `runtest frameworks-wifi` passes.

Change-Id: Ifff78ea540929fde4abea65716e1f659da2ecfec
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index dd5c1e9..6165114 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -140,7 +140,7 @@
             String countryCode, ArrayList<Integer> allowed2GChannels,
             SoftApManager.Listener listener) {
         return new SoftApManager(
-                context, looper, wifiNative, nmService, cm, countryCode,
+                looper, wifiNative, nmService, countryCode,
                 allowed2GChannels, listener);
     }
 
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index f271b4c..2dfb754 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -20,14 +20,8 @@
 import static com.android.server.wifi.util.ApConfigUtil.ERROR_NO_CHANNEL;
 import static com.android.server.wifi.util.ApConfigUtil.SUCCESS;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.ConnectivityManager;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.INetworkManagementService;
@@ -49,31 +43,18 @@
 public class SoftApManager {
     private static final String TAG = "SoftApManager";
 
-    private final Context mContext;
     private final INetworkManagementService mNmService;
     private final WifiNative mWifiNative;
-    private final ConnectivityManager mConnectivityManager;
     private final ArrayList<Integer> mAllowed2GChannels;
 
     private final String mCountryCode;
 
     private final String mInterfaceName;
-    private String mTetherInterfaceName;
 
     private final SoftApStateMachine mStateMachine;
 
     private final Listener mListener;
 
-    private static class TetherStateChange {
-        public ArrayList<String> available;
-        public ArrayList<String> active;
-
-        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
-            available = av;
-            active = ac;
-        }
-    }
-
     /**
      * Listener for soft AP state changes.
      */
@@ -86,40 +67,21 @@
         void onStateChanged(int state, int failureReason);
     }
 
-    public SoftApManager(Context context,
-                         Looper looper,
+    public SoftApManager(Looper looper,
                          WifiNative wifiNative,
                          INetworkManagementService nmService,
-                         ConnectivityManager connectivityManager,
                          String countryCode,
                          ArrayList<Integer> allowed2GChannels,
                          Listener listener) {
         mStateMachine = new SoftApStateMachine(looper);
 
-        mContext = context;
         mNmService = nmService;
         mWifiNative = wifiNative;
-        mConnectivityManager = connectivityManager;
         mCountryCode = countryCode;
         mAllowed2GChannels = allowed2GChannels;
         mListener = listener;
 
         mInterfaceName = mWifiNative.getInterfaceName();
-
-        /* Register receiver for tether state changes. */
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        ArrayList<String> available = intent.getStringArrayListExtra(
-                                ConnectivityManager.EXTRA_AVAILABLE_TETHER);
-                        ArrayList<String> active = intent.getStringArrayListExtra(
-                                ConnectivityManager.EXTRA_ACTIVE_TETHER);
-                        mStateMachine.sendMessage(
-                                SoftApStateMachine.CMD_TETHER_STATE_CHANGE,
-                                new TetherStateChange(available, active));
-                    }
-                }, new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
     }
 
     /**
@@ -208,104 +170,19 @@
         Log.d(TAG, "Soft AP is stopped");
     }
 
-    private boolean startTethering(ArrayList<String> available) {
-        String[] wifiRegexs = mConnectivityManager.getTetherableWifiRegexs();
-
-        for (String intf : available) {
-            for (String regex : wifiRegexs) {
-                if (intf.matches(regex)) {
-                    try {
-                        InterfaceConfiguration ifcg =
-                                mNmService.getInterfaceConfig(intf);
-                        if (ifcg != null) {
-                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
-                            ifcg.setLinkAddress(new LinkAddress(
-                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
-                            ifcg.setInterfaceUp();
-
-                            mNmService.setInterfaceConfig(intf, ifcg);
-                        }
-                    } catch (Exception e) {
-                        Log.e(TAG, "Error configuring interface " + intf + ", :" + e);
-                        return false;
-                    }
-
-                    if (mConnectivityManager.tether(intf)
-                            != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                        Log.e(TAG, "Error tethering on " + intf);
-                        return false;
-                    }
-                    mTetherInterfaceName = intf;
-                    return true;
-                }
-            }
-        }
-        /* We found no interfaces to tether. */
-        return false;
-    }
-
-    private void stopTethering() {
-        try {
-            /* Clear the interface address. */
-            InterfaceConfiguration ifcg =
-                    mNmService.getInterfaceConfig(mTetherInterfaceName);
-            if (ifcg != null) {
-                ifcg.setLinkAddress(
-                        new LinkAddress(
-                                NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
-                mNmService.setInterfaceConfig(mTetherInterfaceName, ifcg);
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Error resetting interface " + mTetherInterfaceName + ", :" + e);
-        }
-
-        if (mConnectivityManager.untether(mTetherInterfaceName)
-                != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-            Log.e(TAG, "Untether initiate failed!");
-        }
-    }
-
-    private boolean isWifiTethered(ArrayList<String> active) {
-        String[] wifiRegexs = mConnectivityManager.getTetherableWifiRegexs();
-        for (String intf : active) {
-            for (String regex : wifiRegexs) {
-                if (intf.matches(regex)) {
-                    return true;
-                }
-            }
-        }
-        /* No tethered interface. */
-        return false;
-    }
-
     private class SoftApStateMachine extends StateMachine {
         /* Commands for the state machine. */
         public static final int CMD_START = 0;
         public static final int CMD_STOP = 1;
-        public static final int CMD_TETHER_STATE_CHANGE = 2;
-        public static final int CMD_TETHER_NOTIFICATION_TIMEOUT = 3;
-
-        private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
-
-        /* Sequence number used to track tether notification timeout. */
-        private int mTetherToken = 0;
 
         private final State mIdleState = new IdleState();
         private final State mStartedState = new StartedState();
-        private final State mTetheringState = new TetheringState();
-        private final State mTetheredState = new TetheredState();
-        private final State mUntetheringState = new UntetheringState();
 
         SoftApStateMachine(Looper looper) {
             super(TAG, looper);
 
-            // CHECKSTYLE:OFF IndentationCheck
             addState(mIdleState);
-                addState(mStartedState, mIdleState);
-                    addState(mTetheringState, mStartedState);
-                    addState(mTetheredState, mStartedState);
-                    addState(mUntetheringState, mStartedState);
-            // CHECKSTYLE:ON IndentationCheck
+            addState(mStartedState, mIdleState);
 
             setInitialState(mIdleState);
             start();
@@ -350,12 +227,6 @@
                         updateApState(WifiManager.WIFI_AP_STATE_DISABLED, 0);
                         transitionTo(mIdleState);
                         break;
-                    case CMD_TETHER_STATE_CHANGE:
-                        TetherStateChange stateChange = (TetherStateChange) message.obj;
-                        if (startTethering(stateChange.available)) {
-                            transitionTo(mTetheringState);
-                        }
-                        break;
                     default:
                         return NOT_HANDLED;
                 }
@@ -363,112 +234,5 @@
             }
         }
 
-        /**
-         * This is a transient state. We will transition out of this state when
-         * we receive a notification that WiFi is tethered (TetheredState) or
-         * we timed out waiting for that notification (StartedState).
-         */
-        private class TetheringState extends State {
-            @Override
-            public void enter() {
-                /* Send a delayed message to terminate if tethering fails to notify. */
-                sendMessageDelayed(
-                        obtainMessage(CMD_TETHER_NOTIFICATION_TIMEOUT, ++mTetherToken),
-                        TETHER_NOTIFICATION_TIME_OUT_MSECS);
-            }
-
-            @Override
-            public boolean processMessage(Message message) {
-                switch (message.what) {
-                    case CMD_TETHER_STATE_CHANGE:
-                        TetherStateChange stateChange = (TetherStateChange) message.obj;
-                        if (isWifiTethered(stateChange.active)) {
-                            transitionTo(mTetheredState);
-                        }
-                        break;
-                    case CMD_TETHER_NOTIFICATION_TIMEOUT:
-                        if (message.arg1 == mTetherToken) {
-                            Log.e(TAG, "Failed to get tether update, "
-                                    + "shutdown soft access point");
-                            transitionTo(mStartedState);
-                            /* Needs to be first thing handled. */
-                            sendMessageAtFrontOfQueue(CMD_STOP);
-                        }
-                        break;
-                    default:
-                        return NOT_HANDLED;
-                }
-                return HANDLED;
-            }
-        }
-
-        private class TetheredState extends State {
-            @Override
-            public boolean processMessage(Message message) {
-                switch (message.what) {
-                    case CMD_TETHER_STATE_CHANGE:
-                        TetherStateChange stateChange = (TetherStateChange) message.obj;
-                        if (!isWifiTethered(stateChange.active)) {
-                            Log.e(TAG, "Tethering reports wifi as untethered!, "
-                                    + "shut down soft Ap");
-                            sendMessage(CMD_STOP);
-                        }
-                        break;
-                    case CMD_STOP:
-                        Log.d(TAG, "Untethering before stopping AP");
-                        stopTethering();
-                        transitionTo(mUntetheringState);
-                        break;
-
-                    default:
-                        return NOT_HANDLED;
-                }
-                return HANDLED;
-            }
-        }
-
-        /**
-         * This is a transient state, will transition out of this state to StartedState
-         * when we receive a notification that WiFi is untethered or we timed out waiting
-         * for that notification.
-         */
-        private class UntetheringState extends State {
-            @Override
-            public void enter() {
-                /* Send a delayed message to terminate if tethering fails to notify. */
-                sendMessageDelayed(
-                        obtainMessage(CMD_TETHER_NOTIFICATION_TIMEOUT, ++mTetherToken),
-                        TETHER_NOTIFICATION_TIME_OUT_MSECS);
-            }
-
-            @Override
-            public boolean processMessage(Message message) {
-                switch (message.what) {
-                    case CMD_TETHER_STATE_CHANGE:
-                        TetherStateChange stateChange = (TetherStateChange) message.obj;
-                        /* Transition back to StartedState when WiFi is untethered. */
-                        if (!isWifiTethered(stateChange.active)) {
-                            transitionTo(mStartedState);
-                            /* Needs to be first thing handled */
-                            sendMessageAtFrontOfQueue(CMD_STOP);
-                        }
-                        break;
-                    case CMD_TETHER_NOTIFICATION_TIMEOUT:
-                        if (message.arg1 == mTetherToken) {
-                            Log.e(TAG, "Failed to get tether update, "
-                                    + "force stop access point");
-                            transitionTo(mStartedState);
-                            /* Needs to be first thing handled. */
-                            sendMessageAtFrontOfQueue(CMD_STOP);
-                        }
-                        break;
-                    default:
-                        /* Defer handling of this message until untethering is completed. */
-                        deferMessage(message);
-                        break;
-                }
-                return HANDLED;
-            }
-        }
     }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index cd63d3f..15432a0 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -20,17 +20,11 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
 import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.INetworkManagementService;
@@ -39,7 +33,6 @@
 
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -57,25 +50,16 @@
     private static final String TEST_INTERFACE_NAME = "TestInterface";
     private static final String TEST_COUNTRY_CODE = "TestCountry";
     private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
-    private static final String[] AVAILABLE_DEVICES = { TEST_INTERFACE_NAME };
 
     private final ArrayList<Integer> mAllowed2GChannels =
             new ArrayList<Integer>(Arrays.asList(ALLOWED_2G_CHANNELS));
 
     TestLooper mLooper;
-    @Mock Context mContext;
     @Mock WifiNative mWifiNative;
     @Mock INetworkManagementService mNmService;
-    @Mock ConnectivityManager mConnectivityManager;
     @Mock SoftApManager.Listener mListener;
     @Mock InterfaceConfiguration mInterfaceConfiguration;
 
-    /**
-     * Internal BroadcastReceiver that SoftApManager uses to listen for tethering
-     * events from ConnectivityManager.
-     */
-    BroadcastReceiver mBroadcastReceiver;
-
     SoftApManager mSoftApManager;
 
     /** Sets up test. */
@@ -87,22 +71,13 @@
         when(mWifiNative.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
         when(mNmService.getInterfaceConfig(TEST_INTERFACE_NAME))
                 .thenReturn(mInterfaceConfiguration);
-        when(mConnectivityManager.getTetherableWifiRegexs())
-                .thenReturn(AVAILABLE_DEVICES);
 
-        mSoftApManager = new SoftApManager(mContext,
-                                           mLooper.getLooper(),
+        mSoftApManager = new SoftApManager(mLooper.getLooper(),
                                            mWifiNative,
                                            mNmService,
-                                           mConnectivityManager,
                                            TEST_COUNTRY_CODE,
                                            mAllowed2GChannels,
                                            mListener);
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mContext).registerReceiver(
-                broadcastReceiverCaptor.capture(), any(IntentFilter.class));
-        mBroadcastReceiver = broadcastReceiverCaptor.getValue();
 
         mLooper.dispatchAll();
     }
@@ -120,35 +95,6 @@
                 WifiManager.WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL);
     }
 
-    /** Tests the handling of timeout after tethering is started. */
-    @Test
-    public void tetheringTimedOut() throws Exception {
-        startSoftApAndVerifyEnabled();
-        announceAvailableForTethering();
-        verifyTetheringRequested();
-
-        InOrder order = inOrder(mListener);
-
-        /* Move the time forward to simulate notification timeout. */
-        mLooper.moveTimeForward(5000);
-        mLooper.dispatchAll();
-
-        /* Verify soft ap is disabled. */
-        verify(mNmService).stopAccessPoint(eq(TEST_INTERFACE_NAME));
-        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
-        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
-    }
-
-    /** Tests the handling of tethered notification after tethering is started. */
-    @Test
-    public void tetherCompleted() throws Exception {
-        startSoftApAndVerifyEnabled();
-        announceAvailableForTethering();
-        verifyTetheringRequested();
-        announceTethered();
-        verifySoftApNotDisabled();
-    }
-
     /** Tests the handling of stop command when soft AP is not started. */
     @Test
     public void stopWhenNotStarted() throws Exception {
@@ -199,31 +145,4 @@
         verify(mListener, never()).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
         verify(mListener, never()).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
     }
-
-    /** Sends a broadcast intent indicating that the interface is available for tethering. */
-    protected void announceAvailableForTethering() throws Exception {
-        when(mConnectivityManager.tether(TEST_INTERFACE_NAME))
-                .thenReturn(ConnectivityManager.TETHER_ERROR_NO_ERROR);
-        ArrayList<String> availableList =
-                new ArrayList<String>(Arrays.asList(AVAILABLE_DEVICES));
-        TestUtil.sendTetherStateChanged(
-                mBroadcastReceiver, mContext, availableList, new ArrayList<String>());
-        mLooper.dispatchAll();
-    }
-
-    /** Verifies that tethering was requested. */
-    protected void verifyTetheringRequested() throws Exception {
-        verify(mInterfaceConfiguration).setLinkAddress(any(LinkAddress.class));
-        verify(mInterfaceConfiguration).setInterfaceUp();
-        verify(mNmService).setInterfaceConfig(eq(TEST_INTERFACE_NAME), eq(mInterfaceConfiguration));
-    }
-
-    /** Sends a broadcast intent indicating that the interface is tethered. */
-    protected void announceTethered() throws Exception {
-        ArrayList<String> deviceList =
-                new ArrayList<String>(Arrays.asList(AVAILABLE_DEVICES));
-        TestUtil.sendTetherStateChanged(
-                mBroadcastReceiver, mContext, deviceList, deviceList);
-        mLooper.dispatchAll();
-    }
 }