diff options
author | Roshan Pius <rpius@google.com> | 2020-12-02 15:16:00 -0800 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2020-12-08 14:56:51 -0800 |
commit | 0db84c1035de103623e9b6be675d06a0e4ca94dc (patch) | |
tree | 00356ec58ee8c75e698b87259ceb04ec32f0a376 | |
parent | 6643805a8d4496333b2d59f122b8e36f33655dfa (diff) | |
download | wifi-0db84c1035de103623e9b6be675d06a0e4ca94dc.tar.gz |
ConcreteClientModeManager: Invoke onStopped() from IdleState exit
Needed to handle stop() call before we have moved to StartedState.
Also,
i) Change the state heirarchy for both ClientModeManager & SoftApManager
to ensure that IdleState is the parent state for all sub-states (helps
put the onStopped() in one central place).
ii) Exit the state machine directly when an interface down/destroyed
callback is received. The current transition to "IdleState" is useless
since the exit of "StartedState" already triggers a state machine exit.
This also causes some weird state transitions currently (Started ->
quitNow() -> Idle -> quit())
Bug: 174119612
Test: atest com.android.server.wifi (Added a test which was failing
before making the changes). All other unit tests passes.
Change-Id: Ib8c15cee44f4dc71df6709274097f7fb1ef2a70f
3 files changed, 42 insertions, 17 deletions
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java index b00b30ff2..4c71190a4 100644 --- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java +++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java @@ -627,9 +627,9 @@ public class ConcreteClientModeManager implements ClientModeManager { // CHECKSTYLE:OFF IndentationCheck addState(mIdleState); - addState(mStartedState); - addState(mScanOnlyModeState, mStartedState); - addState(mConnectModeState, mStartedState); + addState(mStartedState, mIdleState); + addState(mScanOnlyModeState, mStartedState); + addState(mConnectModeState, mStartedState); // CHECKSTYLE:ON IndentationCheck setInitialState(mIdleState); @@ -679,6 +679,11 @@ public class ConcreteClientModeManager implements ClientModeManager { } @Override + public void exit() { + mModeListener.onStopped(ConcreteClientModeManager.this); + } + + @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_START: @@ -766,16 +771,18 @@ public class ConcreteClientModeManager implements ClientModeManager { Log.e(getTag(), "Detected an interface down, reporting failure to " + "SelfRecovery"); mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN); - transitionTo(mIdleState); + // once interface down, nothing else to do... stop the state machine + captureObituaryAndQuitNow(); break; case CMD_INTERFACE_STATUS_CHANGED: boolean isUp = message.arg1 == 1; onUpChanged(isUp); break; case CMD_INTERFACE_DESTROYED: - Log.d(getTag(), "interface destroyed - client mode stopping"); + Log.e(getTag(), "interface destroyed - client mode stopping"); mClientInterfaceName = null; - transitionTo(mIdleState); + // once interface destroyed, nothing else to do... stop the state machine + captureObituaryAndQuitNow(); break; default: return NOT_HANDLED; @@ -794,10 +801,7 @@ public class ConcreteClientModeManager implements ClientModeManager { mIfaceIsUp = false; } - // once we leave started, nothing else to do... stop the state machine mRole = null; - mStateMachine.captureObituaryAndQuitNow(); - mModeListener.onStopped(ConcreteClientModeManager.this); } } diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java index 5e0f64943..fbe3009ba 100644 --- a/service/java/com/android/server/wifi/SoftApManager.java +++ b/service/java/com/android/server/wifi/SoftApManager.java @@ -614,8 +614,10 @@ public class SoftApManager implements ActiveModeManager { SoftApStateMachine(Looper looper) { super(TAG, looper); + // CHECKSTYLE:OFF IndentationCheck addState(mIdleState); - addState(mStartedState); + addState(mStartedState, mIdleState); + // CHECKSTYLE:ON IndentationCheck setInitialState(mIdleState); start(); @@ -630,6 +632,11 @@ public class SoftApManager implements ActiveModeManager { } @Override + public void exit() { + mModeListener.onStopped(SoftApManager.this); + } + + @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_STOP: @@ -934,8 +941,6 @@ public class SoftApManager implements ActiveModeManager { mIfaceIsUp = false; mIfaceIsDestroyed = false; mRole = null; - mStateMachine.quitNow(); - mModeListener.onStopped(SoftApManager.this); updateSoftApInfo(new SoftApInfo()); } @@ -1002,7 +1007,7 @@ public class SoftApManager implements ActiveModeManager { updateApState(WifiManager.WIFI_AP_STATE_DISABLING, WifiManager.WIFI_AP_STATE_ENABLING, 0); } - transitionTo(mIdleState); + quitNow(); break; case CMD_START: // Already started, ignore this command. @@ -1022,14 +1027,14 @@ public class SoftApManager implements ActiveModeManager { Log.i(getTag(), "Timeout message received. Stopping soft AP."); updateApState(WifiManager.WIFI_AP_STATE_DISABLING, WifiManager.WIFI_AP_STATE_ENABLED, 0); - transitionTo(mIdleState); + quitNow(); break; case CMD_INTERFACE_DESTROYED: Log.d(getTag(), "Interface was cleanly destroyed."); updateApState(WifiManager.WIFI_AP_STATE_DISABLING, WifiManager.WIFI_AP_STATE_ENABLED, 0); mIfaceIsDestroyed = true; - transitionTo(mIdleState); + quitNow(); break; case CMD_FAILURE: Log.w(getTag(), "hostapd failure, stop and report failure"); @@ -1041,7 +1046,7 @@ public class SoftApManager implements ActiveModeManager { WifiManager.SAP_START_FAILURE_GENERAL); updateApState(WifiManager.WIFI_AP_STATE_DISABLING, WifiManager.WIFI_AP_STATE_FAILED, 0); - transitionTo(mIdleState); + quitNow(); break; case CMD_UPDATE_CAPABILITY: // Capability should only changed by carrier requirement. Only apply to diff --git a/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java index dbb9f0abf..0109a832b 100644 --- a/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java @@ -438,7 +438,23 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest { } /** - * ClientMode stop properly cleans up state + * ClientMode stop before start has been processed properly cleans up state & invokes the + * onStopped callback. + */ + @Test + public void clientModeStopBeforeStartCleansUpState() throws Exception { + mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY); + // Invoke stop before the inernal start is processed by the state machine. + mClientModeManager.stop(); + mLooper.dispatchAll(); + verify(mListener).onStopped(mClientModeManager); + + // Don't initiate wifi native setup. + verifyNoMoreInteractions(mListener, mWifiNative); + } + + /** + * ClientMode stop properly cleans up state & invokes the onStopped callback. */ @Test public void clientModeStopCleansUpState() throws Exception { |