summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Greenwalt <robdroid@android.com>2010-03-02 17:25:02 -0800
committerRobert Greenwalt <robdroid@android.com>2010-03-03 15:14:29 -0800
commit5a73506cdd466f2b96686ced3ff0f7ca224d1143 (patch)
tree9818d6ef9b3f3dd9658d9ea7eb6ccb9de65d38f5
parent9b10ef5fe85e9d29721ff0cd15161f960d38a8db (diff)
downloadframeworks_base-5a73506cdd466f2b96686ced3ff0f7ca224d1143.zip
frameworks_base-5a73506cdd466f2b96686ced3ff0f7ca224d1143.tar.gz
frameworks_base-5a73506cdd466f2b96686ced3ff0f7ca224d1143.tar.bz2
Add error reporting for Tethering.
Also make the usb interface configuration more robust so retries are possible. Makes all Tethering errors recoverable - no harm letting them try again anyway. Worst case is they need to reboot.
-rw-r--r--core/java/android/net/ConnectivityManager.java60
-rw-r--r--core/java/android/net/IConnectivityManager.aidl8
-rw-r--r--core/java/com/android/internal/app/TetherActivity.java41
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--services/java/com/android/server/ConnectivityService.java34
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java304
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 {