summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeManager.java20
-rw-r--r--service/java/com/android/server/wifi/ScanOnlyModeManager.java18
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java1
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachinePrime.java61
4 files changed, 92 insertions, 8 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 922d21958..b5300d24c 100644
--- a/service/java/com/android/server/wifi/ClientModeManager.java
+++ b/service/java/com/android/server/wifi/ClientModeManager.java
@@ -53,6 +53,8 @@ public class ClientModeManager implements ActiveModeManager {
private String mClientInterfaceName;
private boolean mIfaceIsUp = false;
+ private boolean mExpectedStop = false;
+
ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy,
WifiStateMachine wifiStateMachine) {
@@ -77,6 +79,7 @@ public class ClientModeManager implements ActiveModeManager {
*/
public void stop() {
Log.d(TAG, " currentstate: " + getCurrentStateName());
+ mExpectedStop = true;
if (mClientInterfaceName != null) {
if (mIfaceIsUp) {
updateWifiState(WifiManager.WIFI_STATE_DISABLING,
@@ -127,7 +130,19 @@ public class ClientModeManager implements ActiveModeManager {
* @param currentState current wifi state
*/
private void updateWifiState(int newState, int currentState) {
- mListener.onStateChanged(newState);
+ if (!mExpectedStop) {
+ mListener.onStateChanged(newState);
+ } else {
+ Log.d(TAG, "expected stop, not triggering callbacks: newState = " + newState);
+ }
+
+ // Once we report the mode has stopped/failed any other stop signals are redundant
+ // note: this can happen in failure modes where we get multiple callbacks as underlying
+ // components/interface stops or the underlying interface is destroyed in cleanup
+ if (newState == WifiManager.WIFI_STATE_UNKNOWN
+ || newState == WifiManager.WIFI_STATE_DISABLED) {
+ mExpectedStop = true;
+ }
if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
// do not need to broadcast failure to system
@@ -314,6 +329,9 @@ public class ClientModeManager implements ActiveModeManager {
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_DISABLING);
+
+ // once we leave started, nothing else to do... stop the state machine
+ mStateMachine.quitNow();
}
}
diff --git a/service/java/com/android/server/wifi/ScanOnlyModeManager.java b/service/java/com/android/server/wifi/ScanOnlyModeManager.java
index a98c6ba66..346d2ca67 100644
--- a/service/java/com/android/server/wifi/ScanOnlyModeManager.java
+++ b/service/java/com/android/server/wifi/ScanOnlyModeManager.java
@@ -52,6 +52,8 @@ public class ScanOnlyModeManager implements ActiveModeManager {
private String mClientInterfaceName;
private boolean mIfaceIsUp = false;
+ private boolean mExpectedStop = false;
+
ScanOnlyModeManager(@NonNull Context context, @NonNull Looper looper,
@NonNull WifiNative wifiNative, @NonNull Listener listener,
@NonNull WifiMetrics wifiMetrics,
@@ -78,6 +80,7 @@ public class ScanOnlyModeManager implements ActiveModeManager {
*/
public void stop() {
Log.d(TAG, " currentstate: " + getCurrentStateName());
+ mExpectedStop = true;
mStateMachine.quitNow();
}
@@ -118,6 +121,18 @@ public class ScanOnlyModeManager implements ActiveModeManager {
* @param state new Wifi state
*/
private void updateWifiState(int state) {
+ if (mExpectedStop) {
+ Log.d(TAG, "expected stop, not triggering callbacks: state = " + state);
+ return;
+ }
+
+ // Once we report the mode has stopped/failed any other stop signals are redundant
+ // note: this can happen in failure modes where we get multiple callbacks as underlying
+ // components/interface stops or the underlying interface is destroyed in cleanup
+ if (state == WifiManager.WIFI_STATE_UNKNOWN || state == WifiManager.WIFI_STATE_DISABLED) {
+ mExpectedStop = true;
+ }
+
mListener.onStateChanged(state);
}
@@ -266,6 +281,9 @@ public class ScanOnlyModeManager implements ActiveModeManager {
mClientInterfaceName = null;
}
updateWifiState(WifiManager.WIFI_STATE_DISABLED);
+
+ // once we leave started, nothing else to do... stop the state machine
+ mStateMachine.quitNow();
}
}
}
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 2faf11577..6c52918a5 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -514,6 +514,7 @@ public class SoftApManager implements ActiveModeManager {
WifiManager.WIFI_AP_STATE_DISABLING, 0);
mApInterfaceName = null;
mIfaceIsUp = false;
+ mStateMachine.quitNow();
}
@Override
diff --git a/service/java/com/android/server/wifi/WifiStateMachinePrime.java b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
index fcb199eee..85ea001fb 100644
--- a/service/java/com/android/server/wifi/WifiStateMachinePrime.java
+++ b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
@@ -351,16 +351,24 @@ public class WifiStateMachinePrime {
}
class ClientModeActiveState extends ModeActiveState {
+ ClientListener mListener;
private class ClientListener implements ClientModeManager.Listener {
@Override
public void onStateChanged(int state) {
- Log.d(TAG, "State changed from client mode.");
+ // make sure this listener is still active
+ if (this != mListener) {
+ Log.d(TAG, "Client mode state change from previous manager");
+ return;
+ }
+
+ Log.d(TAG, "State changed from client mode. state = " + state);
+
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
// error while setting up client mode or an unexpected failure.
- mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED);
+ mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
// client mode stopped
- mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED);
+ mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
// client mode is ready to go
Log.d(TAG, "client mode active");
@@ -374,7 +382,8 @@ public class WifiStateMachinePrime {
public void enter() {
Log.d(TAG, "Entering ClientModeActiveState");
- mManager = mWifiInjector.makeClientModeManager(new ClientListener());
+ mListener = new ClientListener();
+ mManager = mWifiInjector.makeClientModeManager(mListener);
mManager.start();
mActiveModeManagers.add(mManager);
@@ -382,6 +391,12 @@ public class WifiStateMachinePrime {
}
@Override
+ public void exit() {
+ super.exit();
+ mListener = null;
+ }
+
+ @Override
public boolean processMessage(Message message) {
if (checkForAndHandleModeChange(message)) {
return HANDLED;
@@ -392,12 +407,21 @@ public class WifiStateMachinePrime {
Log.d(TAG, "Received CMD_START_CLIENT_MODE when active - drop");
break;
case CMD_CLIENT_MODE_FAILED:
+ if (mListener != message.obj) {
+ Log.d(TAG, "Client mode state change from previous manager");
+ return HANDLED;
+ }
Log.d(TAG, "ClientMode failed, return to WifiDisabledState.");
// notify WifiController that ClientMode failed
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
case CMD_CLIENT_MODE_STOPPED:
+ if (mListener != message.obj) {
+ Log.d(TAG, "Client mode state change from previous manager");
+ return HANDLED;
+ }
+
Log.d(TAG, "ClientMode stopped, return to WifiDisabledState.");
// notify WifiController that ClientMode stopped
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
@@ -411,17 +435,23 @@ public class WifiStateMachinePrime {
}
class ScanOnlyModeActiveState extends ModeActiveState {
+ ScanOnlyListener mListener;
private class ScanOnlyListener implements ScanOnlyModeManager.Listener {
@Override
public void onStateChanged(int state) {
+ if (this != mListener) {
+ Log.d(TAG, "ScanOnly mode state change from previous manager");
+ return;
+ }
+
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
Log.d(TAG, "ScanOnlyMode mode failed");
// error while setting up scan mode or an unexpected failure.
- mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_FAILED);
+ mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_FAILED, this);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
Log.d(TAG, "ScanOnlyMode stopped");
//scan only mode stopped
- mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_STOPPED);
+ mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_STOPPED, this);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
// scan mode is ready to go
Log.d(TAG, "scan mode active");
@@ -435,7 +465,8 @@ public class WifiStateMachinePrime {
public void enter() {
Log.d(TAG, "Entering ScanOnlyModeActiveState");
- mManager = mWifiInjector.makeScanOnlyModeManager(new ScanOnlyListener());
+ mListener = new ScanOnlyListener();
+ mManager = mWifiInjector.makeScanOnlyModeManager(mListener);
mManager.start();
mActiveModeManagers.add(mManager);
@@ -444,6 +475,12 @@ public class WifiStateMachinePrime {
}
@Override
+ public void exit() {
+ super.exit();
+ mListener = null;
+ }
+
+ @Override
public boolean processMessage(Message message) {
if (checkForAndHandleModeChange(message)) {
return HANDLED;
@@ -454,12 +491,22 @@ public class WifiStateMachinePrime {
Log.d(TAG, "Received CMD_START_SCAN_ONLY_MODE when active - drop");
break;
case CMD_SCAN_ONLY_MODE_FAILED:
+ if (mListener != message.obj) {
+ Log.d(TAG, "ScanOnly mode state change from previous manager");
+ return HANDLED;
+ }
+
Log.d(TAG, "ScanOnlyMode failed, return to WifiDisabledState.");
// notify WifiController that ScanOnlyMode failed
mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
case CMD_SCAN_ONLY_MODE_STOPPED:
+ if (mListener != message.obj) {
+ Log.d(TAG, "ScanOnly mode state change from previous manager");
+ return HANDLED;
+ }
+
Log.d(TAG, "ScanOnlyMode stopped, return to WifiDisabledState.");
// notify WifiController that ScanOnlyMode stopped
mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);