From 5ea8ed1787d92bce3b07c049e9917cbd6bfc39ef Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 12 May 2020 10:01:42 -0700 Subject: ClientModeImpl: Ignore NETWORK_CONNECTION_EVENT while disconnecting If we've triggered a disconnect, ignore any NETWORK_CONNECTION_EVENTs (triggered if the fw roams just before that). Since we will anyway get a NETWORK_DISCONNECTION_EVENT just after that, reacting to the transient event is not useful. Also, ensure that we explicitly unregister any previous network agent active when creating new one. This is just a failsafe since the fix above should anyway take care of the scenario in this particular bug. Bug: 151067137 Test: atest com.android.server.wifi Test: ACTS presubmit tests Change-Id: I9657c4775922888623794dd749a42378d553ebee Merged-In: I9657c4775922888623794dd749a42378d553ebee --- .../android/server/wifi/ClientModeImplTest.java | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 727922e83..53218f790 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -2454,6 +2454,19 @@ public class ClientModeImplTest extends WifiBaseTest { mLooper.dispatchAll(); } + private void expectUnregisterNetworkAgent() { + // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. + // TODO (b/134538181): consider exposing WifiNetworkAgent and using mocks. + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + mLooper.dispatchAll(); + verify(mNetworkAgentHandler).handleMessage(messageCaptor.capture()); + Message message = messageCaptor.getValue(); + assertNotNull(message); + assertEquals(NetworkAgent.EVENT_NETWORK_INFO_CHANGED, message.what); + NetworkInfo networkInfo = (NetworkInfo) message.obj; + assertEquals(NetworkInfo.DetailedState.DISCONNECTED, networkInfo.getDetailedState()); + } + private void expectNetworkAgentUpdateCapabilities( Consumer networkCapabilitiesChecker) { // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. @@ -5088,4 +5101,33 @@ public class ClientModeImplTest extends WifiBaseTest { verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); } + @Test + public void testIpReachabilityLostAndRoamEventsRace() throws Exception { + connect(); + expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); + reset(mNetworkAgentHandler); + + // Trigger ip reachibility loss and ensure we trigger a disconnect & we're in + // "DisconnectingState" + mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); + mLooper.dispatchAll(); + verify(mWifiNative).disconnect(any()); + assertEquals("DisconnectingState", getCurrentState().getName()); + + // Now send a network connection (indicating a roam) event before we get the disconnect + // event. + mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); + mLooper.dispatchAll(); + // ensure that we ignored the transient roam while we're disconnecting. + assertEquals("DisconnectingState", getCurrentState().getName()); + verifyNoMoreInteractions(mNetworkAgentHandler); + + // Now send the disconnect event and ensure that we transition to "DisconnectedState". + mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); + mLooper.dispatchAll(); + assertEquals("DisconnectedState", getCurrentState().getName()); + expectUnregisterNetworkAgent(); + + verifyNoMoreInteractions(mNetworkAgentHandler); + } } -- cgit v1.2.3