diff options
| -rw-r--r-- | services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java | 46 |
1 files changed, 34 insertions, 12 deletions
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 1ffa86440ae2..601ed010a696 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java @@ -78,7 +78,6 @@ public class TetherInterfaceStateMachine extends StateMachine { public static final int CMD_IPV6_TETHER_UPDATE = BASE_IFACE + 13; private final State mInitialState; - private final State mServingState; private final State mLocalHotspotState; private final State mTetheredState; private final State mUnavailableState; @@ -107,14 +106,12 @@ public class TetherInterfaceStateMachine extends StateMachine { mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; mInitialState = new InitialState(); - mServingState = new ServingState(); mLocalHotspotState = new LocalHotspotState(); mTetheredState = new TetheredState(); mUnavailableState = new UnavailableState(); addState(mInitialState); - addState(mServingState); - addState(mLocalHotspotState, mServingState); - addState(mTetheredState, mServingState); + addState(mLocalHotspotState); + addState(mTetheredState); addState(mUnavailableState); setInitialState(mInitialState); @@ -222,12 +219,11 @@ public class TetherInterfaceStateMachine extends StateMachine { } } - class ServingState extends State { + class BaseServingState extends State { @Override public void enter() { if (!configureIfaceIp(true)) { mLastError = ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR; - transitionTo(mInitialState); return; } @@ -236,12 +232,13 @@ public class TetherInterfaceStateMachine extends StateMachine { } catch (Exception e) { Log.e(TAG, "Error Tethering: " + e.toString()); mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; - transitionTo(mInitialState); return; } if (!mIPv6TetherSvc.start()) { Log.e(TAG, "Failed to start IPv6TetheringInterfaceServices"); + // TODO: Make this a fatal error once Bluetooth IPv6 is sorted. + return; } } @@ -254,9 +251,9 @@ public class TetherInterfaceStateMachine extends StateMachine { try { mNMService.untetherInterface(mIfaceName); - } catch (Exception ee) { + } catch (Exception e) { mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; - Log.e(TAG, "Failed to untether interface: " + ee.toString()); + Log.e(TAG, "Failed to untether interface: " + e.toString()); } configureIfaceIp(false); @@ -293,15 +290,27 @@ public class TetherInterfaceStateMachine extends StateMachine { } } - class LocalHotspotState extends State { + // Handling errors in BaseServingState.enter() by transitioning is + // problematic because transitioning during a multi-state jump yields + // a Log.wtf(). Ultimately, there should be only one ServingState, + // and forwarding and NAT rules should be handled by a coordinating + // functional element outside of TetherInterfaceStateMachine. + class LocalHotspotState extends BaseServingState { @Override public void enter() { + super.enter(); + if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { + transitionTo(mInitialState); + } + if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName); sendInterfaceState(IControlsTethering.STATE_LOCAL_HOTSPOT); } @Override public boolean processMessage(Message message) { + if (super.processMessage(message)) return true; + maybeLogMessage(this, message.what); switch (message.what) { case CMD_TETHER_REQUESTED: @@ -317,9 +326,19 @@ public class TetherInterfaceStateMachine extends StateMachine { } } - class TetheredState extends State { + // Handling errors in BaseServingState.enter() by transitioning is + // problematic because transitioning during a multi-state jump yields + // a Log.wtf(). Ultimately, there should be only one ServingState, + // and forwarding and NAT rules should be handled by a coordinating + // functional element outside of TetherInterfaceStateMachine. + class TetheredState extends BaseServingState { @Override public void enter() { + super.enter(); + if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { + transitionTo(mInitialState); + } + if (DBG) Log.d(TAG, "Tethered " + mIfaceName); sendInterfaceState(IControlsTethering.STATE_TETHERED); } @@ -327,6 +346,7 @@ public class TetherInterfaceStateMachine extends StateMachine { @Override public void exit() { cleanupUpstream(); + super.exit(); } private void cleanupUpstream() { @@ -361,6 +381,8 @@ public class TetherInterfaceStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { + if (super.processMessage(message)) return true; + maybeLogMessage(this, message.what); boolean retValue = true; switch (message.what) { |