Tethering: Own WiFi tethering state and lifetime

( cherry-pick of f1315c3cd6d77e812ae32fe038b4e8bf2e70d5bf )

- Add logic to Tethering to track whether the user has requested
  tethering via WiFi.
- Subscribe to intents regarding soft AP state to enable and
  disable tethering when the AP comes up or goes down.
- Refactor IP configuration logic to do configuration for WiFi
  as well as USB.

Bug: 29054780
Test: WiFi tethering continues to work on angler
      Tethering related unittests continue to pass.

Change-Id: I6eff2573ca3fd11fabcf138c468ba517ff2daf65
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 40d17ed..4a0e81b 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -128,7 +128,7 @@
 
     private Map<String, TetherInterfaceStateMachine> mIfaces; // all tethered/tetherable ifaces
 
-    private BroadcastReceiver mStateReceiver;
+    private final BroadcastReceiver mStateReceiver;
 
     // {@link ComponentName} of the Service used to run tether provisioning.
     private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
@@ -163,6 +163,9 @@
     private boolean mUsbTetherRequested; // true if USB tethering should be started
                                          // when RNDIS is enabled
 
+    // True iff WiFi tethering should be started when soft AP is ready.
+    private boolean mWifiTetherRequested;
+
     public Tethering(Context context, INetworkManagementService nmService,
             INetworkStatsService statsService) {
         mContext = context;
@@ -184,6 +187,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(UsbManager.ACTION_USB_STATE);
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         mContext.registerReceiver(mStateReceiver, filter);
 
@@ -245,29 +249,22 @@
         // Never called directly: only called from interfaceLinkStateChanged.
         // See NetlinkHandler.cpp:71.
         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
-        boolean found = false;
-        boolean usb = false;
         synchronized (mPublicSync) {
-            if (isWifi(iface)) {
-                found = true;
-            } else if (isUsb(iface)) {
-                found = true;
-                usb = true;
-            } else if (isBluetooth(iface)) {
-                found = true;
+            int interfaceType = ifaceNameToType(iface);
+            if (interfaceType == ConnectivityManager.TETHERING_INVALID) {
+                return;
             }
-            if (found == false) return;
 
             TetherInterfaceStateMachine sm = mIfaces.get(iface);
             if (up) {
                 if (sm == null) {
-                    sm = new TetherInterfaceStateMachine(iface, mLooper, usb,
+                    sm = new TetherInterfaceStateMachine(iface, mLooper, interfaceType,
                             mNMService, mStatsService, this);
                     mIfaces.put(iface, sm);
                     sm.start();
                 }
             } else {
-                if (isUsb(iface)) {
+                if (interfaceType == ConnectivityManager.TETHERING_USB) {
                     // ignore usb0 down after enabling RNDIS
                     // we will handle disconnect in interfaceRemoved instead
                     if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
@@ -293,7 +290,7 @@
         }
     }
 
-    public boolean isWifi(String iface) {
+    private boolean isWifi(String iface) {
         synchronized (mPublicSync) {
             for (String regex : mTetherableWifiRegexs) {
                 if (iface.matches(regex)) return true;
@@ -302,7 +299,7 @@
         }
     }
 
-    public boolean isBluetooth(String iface) {
+    private boolean isBluetooth(String iface) {
         synchronized (mPublicSync) {
             for (String regex : mTetherableBluetoothRegexs) {
                 if (iface.matches(regex)) return true;
@@ -311,23 +308,23 @@
         }
     }
 
+    private int ifaceNameToType(String iface) {
+        if (isWifi(iface)) {
+            return ConnectivityManager.TETHERING_WIFI;
+        } else if (isUsb(iface)) {
+            return ConnectivityManager.TETHERING_USB;
+        } else if (isBluetooth(iface)) {
+            return ConnectivityManager.TETHERING_BLUETOOTH;
+        }
+        return ConnectivityManager.TETHERING_INVALID;
+    }
+
     @Override
     public void interfaceAdded(String iface) {
         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
-        boolean found = false;
-        boolean usb = false;
         synchronized (mPublicSync) {
-            if (isWifi(iface)) {
-                found = true;
-            }
-            if (isUsb(iface)) {
-                found = true;
-                usb = true;
-            }
-            if (isBluetooth(iface)) {
-                found = true;
-            }
-            if (found == false) {
+            int interfaceType = ifaceNameToType(iface);
+            if (interfaceType == ConnectivityManager.TETHERING_INVALID) {
                 if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
                 return;
             }
@@ -337,7 +334,7 @@
                 if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
                 return;
             }
-            sm = new TetherInterfaceStateMachine(iface, mLooper, usb,
+            sm = new TetherInterfaceStateMachine(iface, mLooper, interfaceType,
                     mNMService, mStatsService, this);
             mIfaces.put(iface, sm);
             sm.start();
@@ -412,24 +409,19 @@
      * for the specified interface.
      */
     private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
-        boolean isProvisioningRequired = isTetherProvisioningRequired();
+        boolean isProvisioningRequired = enable && isTetherProvisioningRequired();
+        int result;
         switch (type) {
             case ConnectivityManager.TETHERING_WIFI:
-                final WifiManager wifiManager =
-                        (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-                if (wifiManager.setWifiApEnabled(null, enable)) {
-                    sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_NO_ERROR);
-                    if (enable && isProvisioningRequired) {
-                        scheduleProvisioningRechecks(type);
-                    }
-                } else{
-                    sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_MASTER_ERROR);
+                result = setWifiTethering(enable);
+                if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                    scheduleProvisioningRechecks(type);
                 }
+                sendTetherResult(receiver, result);
                 break;
             case ConnectivityManager.TETHERING_USB:
-                int result = setUsbTethering(enable);
-                if (enable && isProvisioningRequired &&
-                        result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                result = setUsbTethering(enable);
+                if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                     scheduleProvisioningRechecks(type);
                 }
                 sendTetherResult(receiver, result);
@@ -449,6 +441,20 @@
         }
     }
 
+    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);
+            if (wifiManager.setWifiApEnabled(null /* use existing wifi config */, enable)) {
+                return ConnectivityManager.TETHER_ERROR_NO_ERROR;
+            }
+            return ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
+        }
+    }
+
     private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter == null || !adapter.isEnabled()) {
@@ -770,7 +776,7 @@
                     mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
                     // start tethering if we have a request pending
                     if (usbConnected && mRndisEnabled && mUsbTetherRequested) {
-                        tetherUsb(true);
+                        tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_USB);
                     }
                     mUsbTetherRequested = false;
                 }
@@ -782,31 +788,72 @@
                     if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
                     mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
                 }
+            } 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) {
+                        case WifiManager.WIFI_AP_STATE_ENABLING:
+                            // 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);
+                            break;
+                        case WifiManager.WIFI_AP_STATE_DISABLED:
+                        case WifiManager.WIFI_AP_STATE_DISABLING:
+                        case WifiManager.WIFI_AP_STATE_FAILED:
+                        default:
+                            if (DBG) {
+                                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);
+                            break;
+                    }
+                }
             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                 updateConfiguration();
             }
         }
     }
 
-    private void tetherUsb(boolean enable) {
-        if (VDBG) Log.d(TAG, "tetherUsb " + enable);
+    private void tetherMatchingInterfaces(boolean enable, int interfaceType) {
+        if (VDBG) Log.d(TAG, "tetherMatchingInterfaces(" + enable + ", " + interfaceType + ")");
 
-        String[] ifaces = new String[0];
+        String[] ifaces = null;
         try {
             ifaces = mNMService.listInterfaces();
         } catch (Exception e) {
             Log.e(TAG, "Error listing Interfaces", e);
             return;
         }
-        for (String iface : ifaces) {
-            if (isUsb(iface)) {
-                int result = (enable ? tether(iface) : untether(iface));
-                if (result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                    return;
+        String chosenIface = null;
+        if (ifaces != null) {
+            for (String iface : ifaces) {
+                if (ifaceNameToType(iface) == interfaceType) {
+                    chosenIface = iface;
+                    break;
                 }
             }
         }
-        Log.e(TAG, "unable start or stop USB tethering");
+        if (chosenIface == null) {
+            Log.e(TAG, "could not find iface of type " + interfaceType);
+            return;
+        }
+
+        int result = (enable ? tether(chosenIface) : untether(chosenIface));
+        if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+            Log.e(TAG, "unable start or stop tethering on iface " + chosenIface);
+            return;
+        }
     }
 
     // TODO - return copies so people can't tamper
@@ -831,7 +878,7 @@
                 if (mRndisEnabled) {
                     final long ident = Binder.clearCallingIdentity();
                     try {
-                        tetherUsb(true);
+                        tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_USB);
                     } finally {
                         Binder.restoreCallingIdentity(ident);
                     }
@@ -842,7 +889,7 @@
             } else {
                 final long ident = Binder.clearCallingIdentity();
                 try {
-                    tetherUsb(false);
+                    tetherMatchingInterfaces(false, ConnectivityManager.TETHERING_USB);
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
@@ -1410,15 +1457,10 @@
                                 for (String iface : ifaces) {
                                     TetherInterfaceStateMachine sm = mIfaces.get(iface);
                                     if (sm != null && sm.isTethered()) {
-                                        if (isUsb(iface)) {
-                                            tethered.add(new Integer(
-                                                    ConnectivityManager.TETHERING_USB));
-                                        } else if (isWifi(iface)) {
-                                            tethered.add(new Integer(
-                                                    ConnectivityManager.TETHERING_WIFI));
-                                        } else if (isBluetooth(iface)) {
-                                            tethered.add(new Integer(
-                                                    ConnectivityManager.TETHERING_BLUETOOTH));
+                                        int interfaceType = ifaceNameToType(iface);
+                                        if (interfaceType !=
+                                                ConnectivityManager.TETHERING_INVALID) {
+                                            tethered.add(new Integer(interfaceType));
                                         }
                                     }
                                 }
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 e33406e6..b8bea60 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -43,6 +43,8 @@
 public class TetherInterfaceStateMachine extends StateMachine {
     private static final String USB_NEAR_IFACE_ADDR = "192.168.42.129";
     private static final int USB_PREFIX_LENGTH = 24;
+    private static final String WIFI_HOST_IFACE_ADDR = "192.168.43.1";
+    private static final int WIFI_HOST_IFACE_PREFIX_LENGTH = 24;
 
     private final static String TAG = "TetherInterfaceSM";
     private final static boolean DBG = false;
@@ -81,13 +83,13 @@
     private final INetworkStatsService mStatsService;
     private final IControlsTethering mTetherController;
 
-    private final boolean mUsb;
     private final String mIfaceName;
+    private final int mInterfaceType;
 
     private int mLastError;
     private String mMyUpstreamIfaceName;  // may change over time
 
-    public TetherInterfaceStateMachine(String ifaceName, Looper looper, boolean usb,
+    public TetherInterfaceStateMachine(String ifaceName, Looper looper, int interfaceType,
                     INetworkManagementService nMService, INetworkStatsService statsService,
                     IControlsTethering tetherController) {
         super(ifaceName, looper);
@@ -95,7 +97,7 @@
         mStatsService = statsService;
         mTetherController = tetherController;
         mIfaceName = ifaceName;
-        mUsb = usb;
+        mInterfaceType = interfaceType;
         setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
 
         mInitialState = new InitialState();
@@ -143,25 +145,38 @@
     }
 
     // configured when we start tethering and unconfig'd on error or conclusion
-    private boolean configureUsbIface(boolean enabled, String iface) {
-        if (VDBG) Log.d(TAG, "configureUsbIface(" + enabled + ")");
+    private boolean configureIfaceIp(boolean enabled) {
+        if (VDBG) Log.d(TAG, "configureIfaceIp(" + enabled + ")");
+
+        String ipAsString = null;
+        int prefixLen = 0;
+        if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
+            ipAsString = USB_NEAR_IFACE_ADDR;
+            prefixLen = USB_PREFIX_LENGTH;
+        } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
+            ipAsString = WIFI_HOST_IFACE_ADDR;
+            prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
+        } else {
+            // Nothing to do, BT does this elsewhere.
+            return true;
+        }
 
         InterfaceConfiguration ifcg = null;
         try {
-            ifcg = mNMService.getInterfaceConfig(iface);
+            ifcg = mNMService.getInterfaceConfig(mIfaceName);
             if (ifcg != null) {
-                InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
-                ifcg.setLinkAddress(new LinkAddress(addr, USB_PREFIX_LENGTH));
+                InetAddress addr = NetworkUtils.numericToInetAddress(ipAsString);
+                ifcg.setLinkAddress(new LinkAddress(addr, prefixLen));
                 if (enabled) {
                     ifcg.setInterfaceUp();
                 } else {
                     ifcg.setInterfaceDown();
                 }
                 ifcg.clearFlag("running");
-                mNMService.setInterfaceConfig(iface, ifcg);
+                mNMService.setInterfaceConfig(mIfaceName, ifcg);
             }
         } catch (Exception e) {
-            Log.e(TAG, "Error configuring interface " + iface, e);
+            Log.e(TAG, "Error configuring interface " + mIfaceName, e);
             return false;
         }
 
@@ -205,12 +220,10 @@
     class TetheredState extends State {
         @Override
         public void enter() {
-            if (mUsb) {
-                if (!configureUsbIface(true, mIfaceName)) {
-                    setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
-                    transitionTo(mInitialState);
-                    return;
-                }
+            if (!configureIfaceIp(true)) {
+                setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
+                transitionTo(mInitialState);
+                return;
             }
 
             try {
@@ -242,9 +255,7 @@
                 Log.e(TAG, "Failed to untether interface: " + ee.toString());
             }
 
-            if (mUsb) {
-                configureUsbIface(false, mIfaceName);
-            }
+            configureIfaceIp(false);
         }
 
         private void cleanupUpstream() {
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index 4410846..30a7dbc 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
 import android.os.INetworkManagementService;
@@ -56,8 +57,8 @@
     private final TestLooper mLooper = new TestLooper();
     private TetherInterfaceStateMachine mTestedSm;
 
-    private void initStateMachine(boolean isUsb) throws Exception {
-        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), isUsb,
+    private void initStateMachine(int interfaceType) throws Exception {
+        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), interfaceType,
                 mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         // Starting the state machine always puts us in a consistent state and notifies
@@ -67,8 +68,8 @@
         when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
     }
 
-    private void initTetheredStateMachine(boolean isUsb, String upstreamIface) throws Exception {
-        initStateMachine(isUsb);
+    private void initTetheredStateMachine(int interfaceType, String upstreamIface) throws Exception {
+        initStateMachine(interfaceType);
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
         if (upstreamIface != null) {
             dispatchTetherConnectionChanged(upstreamIface);
@@ -84,8 +85,8 @@
 
     @Test
     public void startsOutAvailable() {
-        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), false,
-                mNMService, mStatsService, mTetherHelper);
+        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
+                ConnectivityManager.TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         mLooper.dispatchAll();
         assertTrue("Should start out available for tethering", mTestedSm.isAvailable());
@@ -97,7 +98,7 @@
 
     @Test
     public void shouldDoNothingUntilRequested() throws Exception {
-        initStateMachine(false);
+        initStateMachine(ConnectivityManager.TETHERING_BLUETOOTH);
         final int [] NOOP_COMMANDS = {
             TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED,
             TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR,
@@ -117,7 +118,7 @@
 
     @Test
     public void handlesImmediateInterfaceDown() throws Exception {
-        initStateMachine(false);
+        initStateMachine(ConnectivityManager.TETHERING_BLUETOOTH);
         dispatchCommand(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
         verify(mTetherHelper).sendTetherStateChangedBroadcast();
         verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
@@ -129,7 +130,7 @@
 
     @Test
     public void canBeTethered() throws Exception {
-        initStateMachine(false);
+        initStateMachine(ConnectivityManager.TETHERING_BLUETOOTH);
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
         InOrder inOrder = inOrder(mTetherHelper, mNMService);
         inOrder.verify(mTetherHelper).notifyInterfaceTetheringReadiness(true, mTestedSm);
@@ -144,7 +145,7 @@
 
     @Test
     public void canUnrequestTethering() throws Exception {
-        initTetheredStateMachine(false, null);
+        initTetheredStateMachine(ConnectivityManager.TETHERING_BLUETOOTH, null);
 
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
         InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper);
@@ -159,7 +160,7 @@
 
     @Test
     public void canBeTetheredAsUsb() throws Exception {
-        initStateMachine(true);
+        initStateMachine(ConnectivityManager.TETHERING_USB);
 
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
         InOrder inOrder = inOrder(mTetherHelper, mNMService);
@@ -177,7 +178,7 @@
 
     @Test
     public void handlesFirstUpstreamChange() throws Exception {
-        initTetheredStateMachine(false, null);
+        initTetheredStateMachine(ConnectivityManager.TETHERING_BLUETOOTH, null);
 
         // Telling the state machine about its upstream interface triggers a little more configuration.
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);
@@ -192,7 +193,7 @@
 
     @Test
     public void handlesChangingUpstream() throws Exception {
-        initTetheredStateMachine(false, UPSTREAM_IFACE);
+        initTetheredStateMachine(ConnectivityManager.TETHERING_BLUETOOTH, UPSTREAM_IFACE);
 
         dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
         InOrder inOrder = inOrder(mNMService, mStatsService);
@@ -209,7 +210,7 @@
 
     @Test
     public void canUnrequestTetheringWithUpstream() throws Exception {
-        initTetheredStateMachine(false, UPSTREAM_IFACE);
+        initTetheredStateMachine(ConnectivityManager.TETHERING_BLUETOOTH, UPSTREAM_IFACE);
 
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
         InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper);
@@ -228,7 +229,7 @@
     @Test
     public void interfaceDownLeadsToUnavailable() throws Exception {
         for (boolean shouldThrow : new boolean[]{true, false}) {
-            initTetheredStateMachine(true, null);
+            initTetheredStateMachine(ConnectivityManager.TETHERING_USB, null);
 
             if (shouldThrow) {
                 doThrow(RemoteException.class).when(mNMService).untetherInterface(IFACE_NAME);
@@ -246,7 +247,7 @@
 
     @Test
     public void usbShouldBeTornDownOnTetherError() throws Exception {
-        initStateMachine(true);
+        initStateMachine(ConnectivityManager.TETHERING_USB);
 
         doThrow(RemoteException.class).when(mNMService).tetherInterface(IFACE_NAME);
         dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
@@ -263,7 +264,7 @@
 
     @Test
     public void shouldTearDownUsbOnUpstreamError() throws Exception {
-        initTetheredStateMachine(true, null);
+        initTetheredStateMachine(ConnectivityManager.TETHERING_USB, null);
 
         doThrow(RemoteException.class).when(mNMService).enableNat(anyString(), anyString());
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);