Fix dead lock in Tethering state machine
This fix is for tethering from N MR1. It reserves the same idea
originally in e4bdfd8ad86a013c5a2ee8964119393cea1ec4a3.
Tethering is animated by two state machines. If an error occurs,
one of the state machine notifies the other and definitely stays
in the error state while the other retries the tether operation
after having treated the error.
An example is when dnsmasq is started by calling tether(), but while it
hasn't finished starting yet untether() is called asynchronously
by a different tethering. Then "Setting DNS forwarders failed!" error
occurs and device can't be tethered anymore without reboot.
This patch allows to clear the error of the blocked state machine
from the other one and thus recover a normal cycle.
Test: fastly switching USB/Wi-Fi tethering On/Off repeatedly
Test: manually kill dnsmasq during BT tethering then turn on
Wi-Fi tethering
Change-Id: Ide062dd4c15a0e7c72eced9a5fe807f845d4ea9c
This commit is contained in:
committed by
Nguyen Vu Thanh Tung
parent
05550d9ed8
commit
977aad5a65
@@ -950,6 +950,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
// Events from NetworkCallbacks that we process on the master state
|
||||
// machine thread on behalf of the UpstreamNetworkMonitor.
|
||||
static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
|
||||
// we treated the error and want now to clear it
|
||||
static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
|
||||
|
||||
private State mInitialState;
|
||||
private State mTetherModeAliveState;
|
||||
@@ -1487,6 +1489,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
|
||||
who.sendMessage(mErrorNotification);
|
||||
break;
|
||||
case CMD_CLEAR_ERROR:
|
||||
mErrorNotification = ConnectivityManager.TETHER_ERROR_NO_ERROR;
|
||||
transitionTo(mInitialState);
|
||||
break;
|
||||
default:
|
||||
retValue = false;
|
||||
}
|
||||
@@ -1631,6 +1637,12 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
||||
// Not really very much we can do here.
|
||||
}
|
||||
|
||||
// If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
|
||||
// Thus we give a chance for TetherMasterSM to recover to InitialState
|
||||
// by sending CMD_CLEAR_ERROR
|
||||
if (error == ConnectivityManager.TETHER_ERROR_MASTER_ERROR) {
|
||||
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
|
||||
}
|
||||
switch (state) {
|
||||
case IControlsTethering.STATE_UNAVAILABLE:
|
||||
case IControlsTethering.STATE_AVAILABLE:
|
||||
|
||||
@@ -167,7 +167,8 @@ public class TetherInterfaceStateMachine extends StateMachine {
|
||||
private void maybeLogMessage(State state, int what) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, state.getName() + " got " +
|
||||
sMagicDecoderRing.get(what, Integer.toString(what)));
|
||||
sMagicDecoderRing.get(what, Integer.toString(what)) + ", Iface = " +
|
||||
mIfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user