Rely on Tethering mutex for TetherInterfaceSM

( cherry-pick of 4bc8d6b1ac0cb7d4192c829a44d988516f0adbdb )

Stop passing Tethering's mutex into TetherInterfaceSM, and instead
simply rely on Tethering to acquire its own mutex when accessing
instances of TetherInterfaceSM.

While here, remove some boolean fields (previously guarded by the mutex)
which duplicate state information.

Change-Id: Ie6b2128970981786a5d64fbf700c9f3d0a6721fb
Test: Compiles, unittests pass, WiFi tethering continues to work.
Bug: 28910007
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index c26520e..05823b5 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -262,7 +262,7 @@
             TetherInterfaceStateMachine sm = mIfaces.get(iface);
             if (up) {
                 if (sm == null) {
-                    sm = new TetherInterfaceStateMachine(iface, mLooper, usb, mPublicSync,
+                    sm = new TetherInterfaceStateMachine(iface, mLooper, usb,
                             mNMService, mStatsService, this);
                     mIfaces.put(iface, sm);
                     sm.start();
@@ -338,7 +338,7 @@
                 if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
                 return;
             }
-            sm = new TetherInterfaceStateMachine(iface, mLooper, usb, mPublicSync,
+            sm = new TetherInterfaceStateMachine(iface, mLooper, usb,
                     mNMService, mStatsService, this);
             mIfaces.put(iface, sm);
             sm.start();
@@ -576,38 +576,39 @@
 
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
-        TetherInterfaceStateMachine sm = null;
         synchronized (mPublicSync) {
-            sm = mIfaces.get(iface);
+            TetherInterfaceStateMachine sm = mIfaces.get(iface);
+            if (sm == null) {
+                Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
+            }
+            // Ignore the error status of the interface.  If the interface is available,
+            // the errors are referring to past tethering attempts anyway.
+            if (!sm.isAvailable()) {
+                Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
+
+            }
+            sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
+            return ConnectivityManager.TETHER_ERROR_NO_ERROR;
         }
-        if (sm == null) {
-            Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
-        }
-        if (!sm.isAvailable() && !sm.isErrored()) {
-            Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
-        }
-        sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
-        return ConnectivityManager.TETHER_ERROR_NO_ERROR;
     }
 
     public int untether(String iface) {
         if (DBG) Log.d(TAG, "Untethering " + iface);
-        TetherInterfaceStateMachine sm = null;
         synchronized (mPublicSync) {
-            sm = mIfaces.get(iface);
+            TetherInterfaceStateMachine sm = mIfaces.get(iface);
+            if (sm == null) {
+                Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
+            }
+            if (!sm.isTethered()) {
+                Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
+            }
+            sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
+            return ConnectivityManager.TETHER_ERROR_NO_ERROR;
         }
-        if (sm == null) {
-            Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
-        }
-        if (sm.isErrored()) {
-            Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
-        }
-        sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
-        return ConnectivityManager.TETHER_ERROR_NO_ERROR;
     }
 
     public void untetherAll() {
@@ -618,9 +619,8 @@
     }
 
     public int getLastTetherError(String iface) {
-        TetherInterfaceStateMachine sm = null;
         synchronized (mPublicSync) {
-            sm = mIfaces.get(iface);
+            TetherInterfaceStateMachine sm = mIfaces.get(iface);
             if (sm == null) {
                 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
                         ", ignoring");
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 875fc60..0dc910d 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -84,13 +84,10 @@
     private final boolean mUsb;
     private final String mIfaceName;
 
-    private final Object mMutex;  // Protects the fields below.
-    private boolean mAvailable;
-    private boolean mTethered;
     private int mLastError;
     private String mMyUpstreamIfaceName;  // may change over time
 
-    public TetherInterfaceStateMachine(String ifaceName, Looper looper, boolean usb, Object mutex,
+    public TetherInterfaceStateMachine(String ifaceName, Looper looper, boolean usb,
                     INetworkManagementService nMService, INetworkStatsService statsService,
                     IControlsTethering tetherController) {
         super(ifaceName, looper);
@@ -99,7 +96,6 @@
         mTetherController = tetherController;
         mIfaceName = ifaceName;
         mUsb = usb;
-        mMutex = mutex;
         setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
 
         mInitialState = new InitialState();
@@ -127,53 +123,31 @@
     }
 
     public int getLastError() {
-        synchronized (mMutex) {
-            return mLastError;
-        }
+        return mLastError;
     }
 
     private void setLastError(int error) {
-        synchronized (mMutex) {
-            mLastError = error;
+        mLastError = error;
 
-            if (isErrored()) {
-                if (mUsb) {
-                    // note everything's been unwound by this point so nothing to do on
-                    // further error..
-                    configureUsbIface(false, mIfaceName);
-                }
+        if (isErrored()) {
+            if (mUsb) {
+                // note everything's been unwound by this point so nothing to do on
+                // further error..
+                configureUsbIface(false, mIfaceName);
             }
         }
     }
 
     public boolean isAvailable() {
-        synchronized (mMutex) {
-            return mAvailable;
-        }
-    }
-
-    private void setAvailable(boolean available) {
-        synchronized (mMutex) {
-            mAvailable = available;
-        }
+        return getCurrentState() == mInitialState;
     }
 
     public boolean isTethered() {
-        synchronized (mMutex) {
-            return mTethered;
-        }
-    }
-
-    private void setTethered(boolean tethered) {
-        synchronized (mMutex) {
-            mTethered = tethered;
-        }
+        return getCurrentState() == mTetheredState;
     }
 
     public boolean isErrored() {
-        synchronized (mMutex) {
-            return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
-        }
+        return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
     }
 
     // configured when we start tethering and unconfig'd on error or conclusion
@@ -212,8 +186,6 @@
     class InitialState extends State {
         @Override
         public void enter() {
-            setAvailable(true);
-            setTethered(false);
             mTetherController.sendTetherStateChangedBroadcast();
         }
 
@@ -241,7 +213,6 @@
     class TetheredState extends State {
         @Override
         public void enter() {
-            setAvailable(false);
             if (mUsb) {
                 if (!configureUsbIface(true, mIfaceName)) {
                     mTetherController.notifyInterfaceTetheringReadiness(false, TetherInterfaceStateMachine.this);
@@ -267,7 +238,6 @@
                 return;
             }
             if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
-            setTethered(true);
             mTetherController.sendTetherStateChangedBroadcast();
         }
 
@@ -392,9 +362,7 @@
     class UnavailableState extends State {
         @Override
         public void enter() {
-            setAvailable(false);
             setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
-            setTethered(false);
             mTetherController.sendTetherStateChangedBroadcast();
         }
     }
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 f7cc1da..fb5a1cf 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
@@ -48,11 +48,10 @@
     @Mock private InterfaceConfiguration mInterfaceConfiguration;
 
     private final TestLooper mLooper = new TestLooper();
-    private final Object mMutex = new Object();
     private TetherInterfaceStateMachine mTestedSm;
 
     private void initStateMachine(boolean isUsb) {
-        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), isUsb, mMutex,
+        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), isUsb,
                 mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         // Starting the state machine always puts us in a consistent state and notifies
@@ -77,7 +76,7 @@
 
     @Test
     public void startsOutAvailable() {
-        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), false, mMutex,
+        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), false,
                 mNMService, mStatsService, mTetherHelper);
         mTestedSm.start();
         mLooper.dispatchAll();