Merge "Add error reporting for Tethering."
This commit is contained in:
committed by
Android (Google) Code Review
commit
351434bd17
@@ -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.tether(iface);
|
||||
return mService.getTetheringErroredIfaces();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return error A TETHER_ERROR value indicating success or failure type
|
||||
* {@hide}
|
||||
*/
|
||||
public boolean untether(String iface) {
|
||||
public int tether(String iface) {
|
||||
try {
|
||||
return mService.tether(iface);
|
||||
} catch (RemoteException e) {
|
||||
return TETHER_ERROR_SERVICE_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return error A TETHER_ERROR value indicating success or failure type
|
||||
* {@hide}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
|
||||
}
|
||||
if (sm.isErrored()) {
|
||||
Log.e(TAG, "Tried to Tether to an errored iface :" + iface + ", ignoring");
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
void setLastErrorAndTransitionToInitialState(int error) {
|
||||
setLastError(error);
|
||||
transitionTo(mInitialState);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user