am 7b6d238b: Merge "Fix tethering interaction from wifi" into ics-mr1
* commit '7b6d238b7515fdd070c361a03e99e6022f2cd2ba': Fix tethering interaction from wifi
This commit is contained in:
@@ -123,6 +123,8 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
private final LruCache<String, ScanResult> mScanResultCache;
|
private final LruCache<String, ScanResult> mScanResultCache;
|
||||||
|
|
||||||
private String mInterfaceName;
|
private String mInterfaceName;
|
||||||
|
/* Tethering interface could be seperate from wlan interface */
|
||||||
|
private String mTetherInterfaceName;
|
||||||
|
|
||||||
private int mLastSignalLevel = -1;
|
private int mLastSignalLevel = -1;
|
||||||
private String mLastBssid;
|
private String mLastBssid;
|
||||||
@@ -156,6 +158,14 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
/* Tracks sequence number on stop failure message */
|
/* Tracks sequence number on stop failure message */
|
||||||
private int mSupplicantStopFailureToken = 0;
|
private int mSupplicantStopFailureToken = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tether state change notification time out
|
||||||
|
*/
|
||||||
|
private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
|
||||||
|
|
||||||
|
/* Tracks sequence number on a tether notification time out */
|
||||||
|
private int mTetherToken = 0;
|
||||||
|
|
||||||
private LinkProperties mLinkProperties;
|
private LinkProperties mLinkProperties;
|
||||||
|
|
||||||
// Wakelock held during wifi start/stop and driver load/unload
|
// Wakelock held during wifi start/stop and driver load/unload
|
||||||
@@ -240,10 +250,12 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
static final int CMD_REQUEST_AP_CONFIG = BASE + 27;
|
static final int CMD_REQUEST_AP_CONFIG = BASE + 27;
|
||||||
/* Response to access point configuration request */
|
/* Response to access point configuration request */
|
||||||
static final int CMD_RESPONSE_AP_CONFIG = BASE + 28;
|
static final int CMD_RESPONSE_AP_CONFIG = BASE + 28;
|
||||||
/* Set configuration on tether interface */
|
/* Invoked when getting a tether state change notification */
|
||||||
static final int CMD_TETHER_INTERFACE = BASE + 29;
|
static final int CMD_TETHER_STATE_CHANGE = BASE + 29;
|
||||||
|
/* A delayed message sent to indicate tether state change failed to arrive */
|
||||||
|
static final int CMD_TETHER_NOTIFICATION_TIMED_OUT = BASE + 30;
|
||||||
|
|
||||||
static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 30;
|
static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 31;
|
||||||
|
|
||||||
/* Supplicant commands */
|
/* Supplicant commands */
|
||||||
/* Is supplicant alive ? */
|
/* Is supplicant alive ? */
|
||||||
@@ -455,12 +467,25 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
private State mSoftApStartingState = new SoftApStartingState();
|
private State mSoftApStartingState = new SoftApStartingState();
|
||||||
/* Soft ap is running */
|
/* Soft ap is running */
|
||||||
private State mSoftApStartedState = new SoftApStartedState();
|
private State mSoftApStartedState = new SoftApStartedState();
|
||||||
|
/* Soft ap is running and we are waiting for tether notification */
|
||||||
|
private State mTetheringState = new TetheringState();
|
||||||
/* Soft ap is running and we are tethered through connectivity service */
|
/* Soft ap is running and we are tethered through connectivity service */
|
||||||
private State mTetheredState = new TetheredState();
|
private State mTetheredState = new TetheredState();
|
||||||
|
/* Waiting for untether confirmation to stop soft Ap */
|
||||||
|
private State mSoftApStoppingState = new SoftApStoppingState();
|
||||||
|
|
||||||
/* Wait till p2p is disabled */
|
/* Wait till p2p is disabled */
|
||||||
private State mWaitForP2pDisableState = new WaitForP2pDisableState();
|
private State mWaitForP2pDisableState = new WaitForP2pDisableState();
|
||||||
|
|
||||||
|
private class TetherStateChange {
|
||||||
|
ArrayList<String> available;
|
||||||
|
ArrayList<String> active;
|
||||||
|
TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
|
||||||
|
available = av;
|
||||||
|
active = ac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One of {@link WifiManager#WIFI_STATE_DISABLED},
|
* One of {@link WifiManager#WIFI_STATE_DISABLED},
|
||||||
@@ -562,7 +587,9 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
ArrayList<String> available = intent.getStringArrayListExtra(
|
ArrayList<String> available = intent.getStringArrayListExtra(
|
||||||
ConnectivityManager.EXTRA_AVAILABLE_TETHER);
|
ConnectivityManager.EXTRA_AVAILABLE_TETHER);
|
||||||
sendMessage(CMD_TETHER_INTERFACE, available);
|
ArrayList<String> active = intent.getStringArrayListExtra(
|
||||||
|
ConnectivityManager.EXTRA_ACTIVE_TETHER);
|
||||||
|
sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
|
||||||
}
|
}
|
||||||
},new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
|
},new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
|
||||||
|
|
||||||
@@ -603,7 +630,9 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
addState(mSupplicantStoppingState, mDefaultState);
|
addState(mSupplicantStoppingState, mDefaultState);
|
||||||
addState(mSoftApStartingState, mDefaultState);
|
addState(mSoftApStartingState, mDefaultState);
|
||||||
addState(mSoftApStartedState, mDefaultState);
|
addState(mSoftApStartedState, mDefaultState);
|
||||||
|
addState(mTetheringState, mSoftApStartedState);
|
||||||
addState(mTetheredState, mSoftApStartedState);
|
addState(mTetheredState, mSoftApStartedState);
|
||||||
|
addState(mSoftApStoppingState, mDefaultState);
|
||||||
addState(mWaitForP2pDisableState, mDefaultState);
|
addState(mWaitForP2pDisableState, mDefaultState);
|
||||||
|
|
||||||
setInitialState(mInitialState);
|
setInitialState(mInitialState);
|
||||||
@@ -1139,6 +1168,7 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
loge("Error tethering on " + intf);
|
loge("Error tethering on " + intf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
mTetherInterfaceName = intf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1165,11 +1195,27 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
loge("Error resetting interface " + mInterfaceName + ", :" + e);
|
loge("Error resetting interface " + mInterfaceName + ", :" + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
|
if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
|
||||||
loge("Untether initiate failed!");
|
loge("Untether initiate failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isWifiTethered(ArrayList<String> active) {
|
||||||
|
|
||||||
|
checkAndSetConnectivityInstance();
|
||||||
|
|
||||||
|
String[] wifiRegexs = mCm.getTetherableWifiRegexs();
|
||||||
|
for (String intf : active) {
|
||||||
|
for (String regex : wifiRegexs) {
|
||||||
|
if (intf.matches(regex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We found no interfaces that are tethered
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the country code from the system setting value, if any.
|
* Set the country code from the system setting value, if any.
|
||||||
*/
|
*/
|
||||||
@@ -1800,7 +1846,8 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
case CMD_START_AP_SUCCESS:
|
case CMD_START_AP_SUCCESS:
|
||||||
case CMD_START_AP_FAILURE:
|
case CMD_START_AP_FAILURE:
|
||||||
case CMD_STOP_AP:
|
case CMD_STOP_AP:
|
||||||
case CMD_TETHER_INTERFACE:
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
|
case CMD_TETHER_NOTIFICATION_TIMED_OUT:
|
||||||
case CMD_START_SCAN:
|
case CMD_START_SCAN:
|
||||||
case CMD_DISCONNECT:
|
case CMD_DISCONNECT:
|
||||||
case CMD_RECONNECT:
|
case CMD_RECONNECT:
|
||||||
@@ -3284,7 +3331,7 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
case CMD_SET_FREQUENCY_BAND:
|
case CMD_SET_FREQUENCY_BAND:
|
||||||
case CMD_START_PACKET_FILTERING:
|
case CMD_START_PACKET_FILTERING:
|
||||||
case CMD_STOP_PACKET_FILTERING:
|
case CMD_STOP_PACKET_FILTERING:
|
||||||
case CMD_TETHER_INTERFACE:
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
case WifiP2pService.P2P_ENABLE_PENDING:
|
case WifiP2pService.P2P_ENABLE_PENDING:
|
||||||
deferMessage(message);
|
deferMessage(message);
|
||||||
break;
|
break;
|
||||||
@@ -3326,7 +3373,8 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
case CMD_STOP_AP:
|
case CMD_STOP_AP:
|
||||||
if (DBG) log("Stopping Soft AP");
|
if (DBG) log("Stopping Soft AP");
|
||||||
setWifiApState(WIFI_AP_STATE_DISABLING);
|
setWifiApState(WIFI_AP_STATE_DISABLING);
|
||||||
stopTethering();
|
|
||||||
|
/* We have not tethered at this point, so we just shutdown soft Ap */
|
||||||
try {
|
try {
|
||||||
mNwService.stopAccessPoint(mInterfaceName);
|
mNwService.stopAccessPoint(mInterfaceName);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
@@ -3342,10 +3390,10 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
loge("Cannot start supplicant with a running soft AP");
|
loge("Cannot start supplicant with a running soft AP");
|
||||||
setWifiState(WIFI_STATE_UNKNOWN);
|
setWifiState(WIFI_STATE_UNKNOWN);
|
||||||
break;
|
break;
|
||||||
case CMD_TETHER_INTERFACE:
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
ArrayList<String> available = (ArrayList<String>) message.obj;
|
TetherStateChange stateChange = (TetherStateChange) message.obj;
|
||||||
if (startTethering(available)) {
|
if (startTethering(stateChange.available)) {
|
||||||
transitionTo(mTetheredState);
|
transitionTo(mTetheringState);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WifiP2pService.P2P_ENABLE_PENDING:
|
case WifiP2pService.P2P_ENABLE_PENDING:
|
||||||
@@ -3405,6 +3453,58 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TetheringState extends State {
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
if (DBG) log(getName() + "\n");
|
||||||
|
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
|
||||||
|
|
||||||
|
/* Send ourselves a delayed message to shut down if tethering fails to notify */
|
||||||
|
sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
|
||||||
|
++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean processMessage(Message message) {
|
||||||
|
if (DBG) log(getName() + message.toString() + "\n");
|
||||||
|
switch(message.what) {
|
||||||
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
|
TetherStateChange stateChange = (TetherStateChange) message.obj;
|
||||||
|
if (isWifiTethered(stateChange.active)) {
|
||||||
|
transitionTo(mTetheredState);
|
||||||
|
}
|
||||||
|
return HANDLED;
|
||||||
|
case CMD_TETHER_NOTIFICATION_TIMED_OUT:
|
||||||
|
if (message.arg1 == mTetherToken) {
|
||||||
|
loge("Failed to get tether update, shutdown soft access point");
|
||||||
|
setWifiApEnabled(null, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_LOAD_DRIVER:
|
||||||
|
case CMD_UNLOAD_DRIVER:
|
||||||
|
case CMD_START_SUPPLICANT:
|
||||||
|
case CMD_STOP_SUPPLICANT:
|
||||||
|
case CMD_START_AP:
|
||||||
|
case CMD_STOP_AP:
|
||||||
|
case CMD_START_DRIVER:
|
||||||
|
case CMD_STOP_DRIVER:
|
||||||
|
case CMD_SET_SCAN_MODE:
|
||||||
|
case CMD_SET_SCAN_TYPE:
|
||||||
|
case CMD_SET_HIGH_PERF_MODE:
|
||||||
|
case CMD_SET_COUNTRY_CODE:
|
||||||
|
case CMD_SET_FREQUENCY_BAND:
|
||||||
|
case CMD_START_PACKET_FILTERING:
|
||||||
|
case CMD_STOP_PACKET_FILTERING:
|
||||||
|
case WifiP2pService.P2P_ENABLE_PENDING:
|
||||||
|
deferMessage(message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NOT_HANDLED;
|
||||||
|
}
|
||||||
|
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
|
||||||
|
return HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TetheredState extends State {
|
class TetheredState extends State {
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
@@ -3415,13 +3515,89 @@ public class WifiStateMachine extends StateMachine {
|
|||||||
public boolean processMessage(Message message) {
|
public boolean processMessage(Message message) {
|
||||||
if (DBG) log(getName() + message.toString() + "\n");
|
if (DBG) log(getName() + message.toString() + "\n");
|
||||||
switch(message.what) {
|
switch(message.what) {
|
||||||
case CMD_TETHER_INTERFACE:
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
// Ignore any duplicate interface available notifications
|
TetherStateChange stateChange = (TetherStateChange) message.obj;
|
||||||
// when in tethered state
|
if (!isWifiTethered(stateChange.active)) {
|
||||||
|
loge("Tethering reports wifi as untethered!, shut down soft Ap");
|
||||||
|
setWifiApEnabled(null, false);
|
||||||
|
}
|
||||||
return HANDLED;
|
return HANDLED;
|
||||||
|
case CMD_STOP_AP:
|
||||||
|
if (DBG) log("Untethering before stopping AP");
|
||||||
|
setWifiApState(WIFI_AP_STATE_DISABLING);
|
||||||
|
stopTethering();
|
||||||
|
transitionTo(mSoftApStoppingState);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
}
|
}
|
||||||
|
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
|
||||||
|
return HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SoftApStoppingState extends State {
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
if (DBG) log(getName() + "\n");
|
||||||
|
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
|
||||||
|
|
||||||
|
/* Send ourselves a delayed message to shut down if tethering fails to notify */
|
||||||
|
sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
|
||||||
|
++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean processMessage(Message message) {
|
||||||
|
if (DBG) log(getName() + message.toString() + "\n");
|
||||||
|
switch(message.what) {
|
||||||
|
case CMD_TETHER_STATE_CHANGE:
|
||||||
|
TetherStateChange stateChange = (TetherStateChange) message.obj;
|
||||||
|
|
||||||
|
/* Wait till wifi is untethered */
|
||||||
|
if (isWifiTethered(stateChange.active)) break;
|
||||||
|
|
||||||
|
try {
|
||||||
|
mNwService.stopAccessPoint(mInterfaceName);
|
||||||
|
} catch(Exception e) {
|
||||||
|
loge("Exception in stopAccessPoint()");
|
||||||
|
}
|
||||||
|
transitionTo(mDriverLoadedState);
|
||||||
|
break;
|
||||||
|
case CMD_TETHER_NOTIFICATION_TIMED_OUT:
|
||||||
|
if (message.arg1 == mTetherToken) {
|
||||||
|
loge("Failed to get tether update, force stop access point");
|
||||||
|
try {
|
||||||
|
mNwService.stopAccessPoint(mInterfaceName);
|
||||||
|
} catch(Exception e) {
|
||||||
|
loge("Exception in stopAccessPoint()");
|
||||||
|
}
|
||||||
|
transitionTo(mDriverLoadedState);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_LOAD_DRIVER:
|
||||||
|
case CMD_UNLOAD_DRIVER:
|
||||||
|
case CMD_START_SUPPLICANT:
|
||||||
|
case CMD_STOP_SUPPLICANT:
|
||||||
|
case CMD_START_AP:
|
||||||
|
case CMD_STOP_AP:
|
||||||
|
case CMD_START_DRIVER:
|
||||||
|
case CMD_STOP_DRIVER:
|
||||||
|
case CMD_SET_SCAN_MODE:
|
||||||
|
case CMD_SET_SCAN_TYPE:
|
||||||
|
case CMD_SET_HIGH_PERF_MODE:
|
||||||
|
case CMD_SET_COUNTRY_CODE:
|
||||||
|
case CMD_SET_FREQUENCY_BAND:
|
||||||
|
case CMD_START_PACKET_FILTERING:
|
||||||
|
case CMD_STOP_PACKET_FILTERING:
|
||||||
|
case WifiP2pService.P2P_ENABLE_PENDING:
|
||||||
|
deferMessage(message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NOT_HANDLED;
|
||||||
|
}
|
||||||
|
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
|
||||||
|
return HANDLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user