diff options
-rw-r--r-- | core/java/android/net/ConnectivityManager.java | 60 | ||||
-rw-r--r-- | core/java/android/net/IConnectivityManager.aidl | 8 | ||||
-rw-r--r-- | core/java/com/android/internal/app/TetherActivity.java | 41 | ||||
-rw-r--r-- | core/res/res/values/strings.xml | 9 | ||||
-rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 34 | ||||
-rw-r--r-- | services/java/com/android/server/connectivity/Tethering.java | 304 |
6 files changed, 255 insertions, 201 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index c76aca1..a6668e7 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -364,7 +364,7 @@ public class ConnectivityManager /** * Sets the persisted value for enabling/disabling Mobile data. * - * @param allowMobileData Whether the mobile data connection should be + * @param enabled Whether the mobile data connection should be * used or not. * @hide */ @@ -418,22 +418,35 @@ public class ConnectivityManager /** * {@hide} */ - public boolean tether(String iface) { + public String[] getTetheringErroredIfaces() { + try { + return mService.getTetheringErroredIfaces(); + } catch (RemoteException e) { + return new String[0]; + } + } + + /** + * @return error A TETHER_ERROR value indicating success or failure type + * {@hide} + */ + public int tether(String iface) { try { return mService.tether(iface); } catch (RemoteException e) { - return false; + return TETHER_ERROR_SERVICE_UNAVAIL; } } /** + * @return error A TETHER_ERROR value indicating success or failure type * {@hide} */ - public boolean untether(String iface) { + public int untether(String iface) { try { return mService.untether(iface); } catch (RemoteException e) { - return false; + return TETHER_ERROR_SERVICE_UNAVAIL; } } @@ -469,4 +482,41 @@ public class ConnectivityManager return new String[0]; } } + + /** {@hide} */ + public static final int TETHER_ERROR_NO_ERROR = 0; + /** {@hide} */ + public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; + /** {@hide} */ + public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; + /** {@hide} */ + public static final int TETHER_ERROR_UNSUPPORTED = 3; + /** {@hide} */ + public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; + /** {@hide} */ + public static final int TETHER_ERROR_MASTER_ERROR = 5; + /** {@hide} */ + public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; + /** {@hide} */ + public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; + /** {@hide} */ + public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; + /** {@hide} */ + public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; + /** {@hide} */ + public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; + + /** + * @param iface The name of the interface we're interested in + * @return error The error code of the last error tethering or untethering the named + * interface + * {@hide} + */ + public int getLastTetherError(String iface) { + try { + return mService.getLastTetherError(iface); + } catch (RemoteException e) { + return TETHER_ERROR_SERVICE_UNAVAIL; + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 2514693..b05c2ed 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -55,9 +55,11 @@ interface IConnectivityManager void setMobileDataEnabled(boolean enabled); - boolean tether(String iface); + int tether(String iface); - boolean untether(String iface); + int untether(String iface); + + int getLastTetherError(String iface); boolean isTetheringSupported(); @@ -65,6 +67,8 @@ interface IConnectivityManager String[] getTetheredIfaces(); + String[] getTetheringErroredIfaces(); + String[] getTetherableUsbRegexs(); String[] getTetherableWifiRegexs(); diff --git a/core/java/com/android/internal/app/TetherActivity.java b/core/java/com/android/internal/app/TetherActivity.java index 5d71231..7f83b2b 100644 --- a/core/java/com/android/internal/app/TetherActivity.java +++ b/core/java/com/android/internal/app/TetherActivity.java @@ -62,6 +62,7 @@ public class TetherActivity extends AlertActivity implements // determine if we advertise tethering or untethering ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); + mTethered = cm.getTetheredIfaces().length; int tetherable = cm.getTetherableIfaces().length; if ((mTethered == 0) && (tetherable == 0)) { @@ -116,7 +117,7 @@ public class TetherActivity extends AlertActivity implements * {@inheritDoc} */ public void onClick(DialogInterface dialog, int which) { - boolean error = false; + int error = ConnectivityManager.TETHER_ERROR_NO_ERROR; if (which == POSITIVE_BUTTON) { ConnectivityManager cm = @@ -130,24 +131,17 @@ public class TetherActivity extends AlertActivity implements for (String t : tetherable) { for (String r : usbRegexs) { if (t.matches(r)) { - if (!cm.tether(t)) - error = true; + error = cm.tether(t); break; } } } - if (error) { - showTetheringError(); - } + showTetheringError(error); } else { for (String t : tethered) { - if (!cm.untether(t)) { - error = true; - } - } - if (error) { - showUnTetheringError(); + error = cm.untether(t); } + showUnTetheringError(error); } } // No matter what, finish the activity @@ -163,14 +157,23 @@ public class TetherActivity extends AlertActivity implements } } - private void showTetheringError() { - Toast.makeText(this, com.android.internal.R.string.tether_error_message, - Toast.LENGTH_LONG).show(); + private void showTetheringError(int error) { + switch(error) { + case ConnectivityManager.TETHER_ERROR_NO_ERROR: + return; + default: + Toast.makeText(this, com.android.internal.R.string.tether_error_message, + Toast.LENGTH_LONG).show(); + } } - private void showUnTetheringError() { - Toast.makeText(this, com.android.internal.R.string.tether_stop_error_message, - Toast.LENGTH_LONG).show(); + private void showUnTetheringError(int error) { + switch(error) { + case ConnectivityManager.TETHER_ERROR_NO_ERROR: + return; + default: + Toast.makeText(this, com.android.internal.R.string.tether_stop_error_message, + Toast.LENGTH_LONG).show(); + } } - } diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 35ea0cc..d34599f 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2249,8 +2249,10 @@ <string name="tether_button">Tether</string> <!-- See TETHER. This is the button text to ignore the plugging in of the phone.. --> <string name="tether_button_cancel">Cancel</string> - <!-- See TETHER. If there was an error mounting, this is the text. --> - <string name="tether_error_message">There is a problem tethering.</string> + + <!-- See TETHER. If there was a recoverable error, this is the text. --> + <string name="tether_error_message">We\'ve encountered a problem turning on Tethering. Please try again.</string> + <!-- TETHER: When the user connects the phone to a computer, we show a notification asking if he wants to share his cellular network connection. This is the title --> <string name="tether_available_notification_title">USB tethering available</string> <!-- See USB_STORAGE. This is the message. --> @@ -2270,7 +2272,8 @@ <string name="tether_stop_button">Disconnect</string> <!-- See TETHER_STOP. This is the button text to cancel disconnecting the tether. --> <string name="tether_stop_button_cancel">Cancel</string> - <!-- See TETHER_STOP_DIALOG. If there was an error disconnect, this is the text. --> + + <!-- See TETHER_STOP. If there was an error disconnect, this is the text. --> <string name="tether_stop_error_message">We\'ve encountered a problem turning off Tethering. Please try again.</string> <!-- Strings for car mode notification --> diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 67b6200..a1c45dc 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1457,15 +1457,36 @@ public class ConnectivityService extends IConnectivityManager.Stub { } // javadoc from interface - public boolean tether(String iface) { + public int tether(String iface) { enforceTetherChangePermission(); - return isTetheringSupported() && mTethering.tether(iface); + + if (isTetheringSupported()) { + return mTethering.tether(iface); + } else { + return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; + } } // javadoc from interface - public boolean untether(String iface) { + public int untether(String iface) { enforceTetherChangePermission(); - return isTetheringSupported() && mTethering.untether(iface); + + if (isTetheringSupported()) { + return mTethering.untether(iface); + } else { + return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; + } + } + + // javadoc from interface + public int getLastTetherError(String iface) { + enforceTetherAccessPermission(); + + if (isTetheringSupported()) { + return mTethering.getLastTetherError(iface); + } else { + return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; + } } // TODO - proper iface API for selection by property, inspection, etc @@ -1499,6 +1520,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { return mTethering.getTetheredIfaces(); } + public String[] getTetheringErroredIfaces() { + enforceTetherAccessPermission(); + return mTethering.getErroredIfaces(); + } + // if ro.tether.denied = true we default to no tethering // gservices could set the secure setting to 1 though to enable it on a build where it // had previously been turned off. diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 5f37a42..ee54f73 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -40,6 +40,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.util.Log; +import android.widget.Toast; import com.android.internal.telephony.Phone; import com.android.internal.util.HierarchicalState; @@ -236,7 +237,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } - public boolean tether(String iface) { + public int tether(String iface) { Log.d(TAG, "Tethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { @@ -244,21 +245,17 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } if (sm == null) { Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring"); - return false; - } - if (sm.isErrored()) { - Log.e(TAG, "Tried to Tether to an errored iface :" + iface + ", ignoring"); - return false; + return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; } - if (!sm.isAvailable()) { + if (!sm.isAvailable() && !sm.isErrored()) { Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring"); - return false; + return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; } sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED)); - return true; + return ConnectivityManager.TETHER_ERROR_NO_ERROR; } - public boolean untether(String iface) { + public int untether(String iface) { Log.d(TAG, "Untethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { @@ -266,14 +263,26 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } if (sm == null) { Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); - return false; + return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; } if (sm.isErrored()) { Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring"); - return false; + return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; } sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED)); - return true; + return ConnectivityManager.TETHER_ERROR_NO_ERROR; + } + + public int getLastTetherError(String iface) { + TetherInterfaceSM sm = null; + synchronized (mIfaces) { + sm = mIfaces.get(iface); + } + if (sm == null) { + Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); + return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; + } + return sm.getLastError(); } private void sendTetherStateChangedBroadcast() { @@ -430,6 +439,28 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } + private void showErrorToast(int error) { + int num; + switch(error) { + case ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR: + case ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR: + case ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR: + case ConnectivityManager.TETHER_ERROR_MASTER_ERROR: + num = com.android.internal.R.string.tether_error_message; + break; + case ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR: + case ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR: + num = com.android.internal.R.string.tether_stop_error_message; + break; + default: + // do nothing + return; + } + String text = mContext.getResources().getString(num) + " - EC" + error; + Log.e(TAG, text); + Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); + } + private class StateReceiver extends BroadcastReceiver { public void onReceive(Context content, Intent intent) { String action = intent.getAction(); @@ -542,10 +573,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub { ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up"); } else { ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down"); - // TODO - clean this up - maybe a better regex? - ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", ""); - ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," "); } + ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", ""); + ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," "); service.setInterfaceConfig(iface, ifcg); } } catch (Exception e) { @@ -611,6 +641,24 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return retVal; } + public String[] getErroredIfaces() { + ArrayList<String> list = new ArrayList<String>(); + synchronized (mIfaces) { + Set keys = mIfaces.keySet(); + for (Object key : keys) { + TetherInterfaceSM sm = mIfaces.get(key); + if (sm.isErrored()) { + list.add((String)key); + } + } + } + String[] retVal = new String[list.size()]; + for (int i= 0; i< list.size(); i++) { + retVal[i] = list.get(i); + } + return retVal; + } + class TetherInterfaceSM extends HierarchicalStateMachine { // notification from the master SM that it's in tether mode @@ -637,8 +685,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { static final int CMD_STOP_TETHERING_ERROR = 14; // notification from the master SM that it had trouble setting the DNS forwarders static final int CMD_SET_DNS_FORWARDERS_ERROR = 15; - // a mechanism to transition self to error state from an enter function - static final int CMD_TRANSITION_TO_ERROR = 16; + // a mechanism to transition self to another state from an enter function + static final int CMD_TRANSITION_TO_STATE = 16; private HierarchicalState mDefaultState; @@ -646,18 +694,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private HierarchicalState mStartingState; private HierarchicalState mTetheredState; - private HierarchicalState mMasterTetherErrorState; - private HierarchicalState mTetherInterfaceErrorState; - private HierarchicalState mUntetherInterfaceErrorState; - private HierarchicalState mEnableNatErrorState; - private HierarchicalState mDisableNatErrorState; - private HierarchicalState mUsbConfigurationErrorState; - private HierarchicalState mUnavailableState; private boolean mAvailable; - private boolean mErrored; private boolean mTethered; + int mLastError; String mIfaceName; boolean mUsb; @@ -666,6 +707,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { super(name); mIfaceName = name; mUsb = usb; + setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); mInitialState = new InitialState(); addState(mInitialState); @@ -673,18 +715,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { addState(mStartingState); mTetheredState = new TetheredState(); addState(mTetheredState); - mMasterTetherErrorState = new MasterTetherErrorState(); - addState(mMasterTetherErrorState); - mTetherInterfaceErrorState = new TetherInterfaceErrorState(); - addState(mTetherInterfaceErrorState); - mUntetherInterfaceErrorState = new UntetherInterfaceErrorState(); - addState(mUntetherInterfaceErrorState); - mEnableNatErrorState = new EnableNatErrorState(); - addState(mEnableNatErrorState); - mDisableNatErrorState = new DisableNatErrorState(); - addState(mDisableNatErrorState); - mUsbConfigurationErrorState = new UsbConfigurationErrorState(); - addState(mUsbConfigurationErrorState); mUnavailableState = new UnavailableState(); addState(mUnavailableState); @@ -698,19 +728,30 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (current == mInitialState) res += "InitialState"; if (current == mStartingState) res += "StartingState"; if (current == mTetheredState) res += "TetheredState"; - if (current == mMasterTetherErrorState) res += "MasterTetherErrorState"; - if (current == mTetherInterfaceErrorState) res += "TetherInterfaceErrorState"; - if (current == mUntetherInterfaceErrorState) res += "UntetherInterfaceErrorState"; - if (current == mEnableNatErrorState) res += "EnableNatErrorState"; - if (current == mDisableNatErrorState) res += "DisableNatErrorState"; - if (current == mUsbConfigurationErrorState) res += "UsbConfigurationErrorState"; if (current == mUnavailableState) res += "UnavailableState"; if (mAvailable) res += " - Available"; if (mTethered) res += " - Tethered"; - if (mErrored) res += " - ERRORED"; + res += " - lastError =" + mLastError; return res; } + public synchronized int getLastError() { + return mLastError; + } + + private synchronized void setLastError(int error) { + mLastError = error; + + if (isErrored()) { + if (mUsb) { + // note everything's been unwound by this point so nothing to do on + // further error.. + Tethering.this.configureUsbIface(false); + } + Tethering.this.showErrorToast(error); + } + } + // synchronized between this getter and the following setter public synchronized boolean isAvailable() { return mAvailable; @@ -731,18 +772,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { // synchronized between this getter and the following setter public synchronized boolean isErrored() { - return mErrored; - } - - private void setErrored(boolean errored) { - synchronized (this) { - mErrored = errored; - } - if (errored && mUsb) { - // note everything's been unwound by this point so nothing to do on - // further error.. - Tethering.this.configureUsbIface(false); - } + return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR); } class InitialState extends HierarchicalState { @@ -750,7 +780,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void enter() { setAvailable(true); setTethered(false); - setErrored(false); sendTetherStateChangedBroadcast(); } @@ -760,6 +789,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean retValue = true; switch (message.what) { case CMD_TETHER_REQUESTED: + setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); Message m = mTetherMasterSM.obtainMessage( TetherMasterSM.CMD_TETHER_MODE_REQUESTED); m.obj = TetherInterfaceSM.this; @@ -788,8 +818,10 @@ public class Tethering extends INetworkManagementEventObserver.Stub { m.obj = TetherInterfaceSM.this; mTetherMasterSM.sendMessage(m); - m = obtainMessage(CMD_TRANSITION_TO_ERROR); - m.obj = mUsbConfigurationErrorState; + setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); + + m = obtainMessage(CMD_TRANSITION_TO_STATE); + m.obj = mInitialState; sendMessageAtFrontOfQueue(m); return; } @@ -809,7 +841,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mTetherMasterSM.sendMessage(m); if (mUsb) { if (!Tethering.this.configureUsbIface(false)) { - transitionTo(mUsbConfigurationErrorState); + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); break; } } @@ -824,7 +857,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { case CMD_START_TETHERING_ERROR: case CMD_STOP_TETHERING_ERROR: case CMD_SET_DNS_FORWARDERS_ERROR: - transitionTo(mMasterTetherErrorState); + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_MASTER_ERROR); break; case CMD_INTERFACE_DOWN: m = mTetherMasterSM.obtainMessage( @@ -833,7 +867,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mTetherMasterSM.sendMessage(m); transitionTo(mUnavailableState); break; - case CMD_TRANSITION_TO_ERROR: + case CMD_TRANSITION_TO_STATE: HierarchicalState s = (HierarchicalState)(message.obj); transitionTo(s); break; @@ -853,16 +887,24 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { service.tetherInterface(mIfaceName); } catch (Exception e) { - Message m = obtainMessage(CMD_TRANSITION_TO_ERROR); - m.obj = mTetherInterfaceErrorState; + setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); + + Message m = obtainMessage(CMD_TRANSITION_TO_STATE); + m.obj = mInitialState; sendMessageAtFrontOfQueue(m); return; } try { service.enableNat(mIfaceName, mUpstreamIfaceName); } catch (Exception e) { - Message m = obtainMessage(CMD_TRANSITION_TO_ERROR); - m.obj = mEnableNatErrorState; + try { + service.untetherInterface(mIfaceName); + } catch (Exception ee) {} + + setLastError(ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR); + + Message m = obtainMessage(CMD_TRANSITION_TO_STATE); + m.obj = mInitialState; sendMessageAtFrontOfQueue(m); return; } @@ -890,13 +932,19 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { service.disableNat(mIfaceName, mUpstreamIfaceName); } catch (Exception e) { - transitionTo(mDisableNatErrorState); + try { + service.untetherInterface(mIfaceName); + } catch (Exception ee) {} + + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); break; } try { service.untetherInterface(mIfaceName); } catch (Exception e) { - transitionTo(mUntetherInterfaceErrorState); + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); break; } Message m = mTetherMasterSM.obtainMessage( @@ -906,13 +954,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (message.what == CMD_TETHER_UNREQUESTED) { if (mUsb) { if (!Tethering.this.configureUsbIface(false)) { - transitionTo(mUsbConfigurationErrorState); - } else { - transitionTo(mInitialState); + setLastError( + ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); } - } else { - transitionTo(mInitialState); } + transitionTo(mInitialState); } else if (message.what == CMD_INTERFACE_DOWN) { transitionTo(mUnavailableState); } @@ -932,30 +978,36 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { service.disableNat(mIfaceName, mUpstreamIfaceName); } catch (Exception e) { - transitionTo(mDisableNatErrorState); + try { + service.untetherInterface(mIfaceName); + } catch (Exception ee) {} + + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_DISABLE_NAT_ERROR); break; } try { service.untetherInterface(mIfaceName); } catch (Exception e) { - transitionTo(mUntetherInterfaceErrorState); + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR); break; } if (error) { - transitionTo(mMasterTetherErrorState); + setLastErrorAndTransitionToInitialState( + ConnectivityManager.TETHER_ERROR_MASTER_ERROR); break; } Log.d(TAG, "Tether lost upstream connection " + mIfaceName); sendTetherStateChangedBroadcast(); if (mUsb) { if (!Tethering.this.configureUsbIface(false)) { - transitionTo(mUsbConfigurationErrorState); - break; + setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR); } } transitionTo(mInitialState); break; - case CMD_TRANSITION_TO_ERROR: + case CMD_TRANSITION_TO_STATE: HierarchicalState s = (HierarchicalState)(message.obj); transitionTo(s); break; @@ -971,7 +1023,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { @Override public void enter() { setAvailable(false); - setErrored(false); + setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR); setTethered(false); sendTetherStateChangedBroadcast(); } @@ -990,95 +1042,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } - - class ErrorState extends HierarchicalState { - int mErrorNotification; - @Override - public boolean processMessage(Message message) { - boolean retValue = true; - switch (message.what) { - case CMD_TETHER_REQUESTED: - sendTetherStateChangedBroadcast(); - break; - default: - retValue = false; - break; - } - return retValue; - } - } - - class MasterTetherErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error in Master Tether state " + mIfaceName); - setAvailable(false); - setErrored(true); - sendTetherStateChangedBroadcast(); - } - } - - class TetherInterfaceErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error trying to tether " + mIfaceName); - setAvailable(false); - setErrored(true); - sendTetherStateChangedBroadcast(); - } - } - - class UntetherInterfaceErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error trying to untether " + mIfaceName); - setAvailable(false); - setErrored(true); - sendTetherStateChangedBroadcast(); - } - } - - class EnableNatErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error trying to enable NAT " + mIfaceName); - setAvailable(false); - setErrored(true); - - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); - try { - service.untetherInterface(mIfaceName); - } catch (Exception e) {} - sendTetherStateChangedBroadcast(); - } - } - - - class DisableNatErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error trying to disable NAT " + mIfaceName); - setAvailable(false); - setErrored(true); - - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); - try { - service.untetherInterface(mIfaceName); - } catch (Exception e) {} - sendTetherStateChangedBroadcast(); - } + void setLastErrorAndTransitionToInitialState(int error) { + setLastError(error); + transitionTo(mInitialState); } - class UsbConfigurationErrorState extends ErrorState { - @Override - public void enter() { - Log.e(TAG, "Error trying to configure USB " + mIfaceName); - setAvailable(false); - setErrored(true); - } - } } class TetherMasterSM extends HierarchicalStateMachine { |