diff options
author | Rebecca Silberstein <silberst@google.com> | 2018-01-24 02:27:42 -0800 |
---|---|---|
committer | Rebecca Silberstein <silberst@google.com> | 2018-03-09 02:59:49 -0800 |
commit | e845cb0859529bf544208dc5d5711535231a04c0 (patch) | |
tree | b04679105560d34f4d833b7ad97d0f0ec111004e /tests | |
parent | 34226fdc35f33a5c3a95e0b86138c933c5682370 (diff) |
ClientModeManager: add interface control
Add interface control using the new WifiNative APIs to
ClientModeManager. Unit tests are also added to cover interface
creation and teardown events.
Bug: 32941234
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I367c649be5e5c5b7e0925583e9479cef72ed5c77
Diffstat (limited to 'tests')
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java new file mode 100644 index 000000000..942ff1c8b --- /dev/null +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java @@ -0,0 +1,315 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi; + +import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_STATE; +import static android.net.wifi.WifiManager.EXTRA_SCAN_AVAILABLE; +import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE; +import static android.net.wifi.WifiManager.WIFI_SCAN_AVAILABLE; +import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION; +import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; +import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; +import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; +import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; +import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +import android.content.Context; +import android.content.Intent; +import android.os.UserHandle; +import android.os.test.TestLooper; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.List; + +/** + * Unit tests for {@link ClientModeManager}. + */ +@SmallTest +public class ClientModeManagerTest { + private static final String TAG = "ClientModeManagerTest"; + private static final String TEST_INTERFACE_NAME = "testif0"; + private static final String OTHER_INTERFACE_NAME = "notTestIf"; + + TestLooper mLooper; + + ClientModeManager mClientModeManager; + + @Mock Context mContext; + @Mock WifiMetrics mWifiMetrics; + @Mock WifiNative mWifiNative; + @Mock ClientModeManager.Listener mListener; + @Mock WifiMonitor mWifiMonitor; + @Mock ScanRequestProxy mScanRequestProxy; + + final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor = + ArgumentCaptor.forClass(WifiNative.StatusListener.class); + final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor = + ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class); + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mLooper = new TestLooper(); + + mClientModeManager = createClientModeManager(); + mLooper.dispatchAll(); + } + + private ClientModeManager createClientModeManager() { + return new ClientModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener, + mWifiMetrics, mScanRequestProxy); + } + + private void startClientModeAndVerifyEnabled() throws Exception { + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + + when(mWifiNative.setupInterfaceForClientMode(eq(false), any())) + .thenReturn(TEST_INTERFACE_NAME); + mClientModeManager.start(); + mLooper.dispatchAll(); + + verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture()); + verify(mWifiNative).setupInterfaceForClientMode( + eq(false), mInterfaceCallbackCaptor.capture()); + + // now mark the interface as up + mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME); + mLooper.dispatchAll(); + + verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), + eq(UserHandle.ALL)); + + List<Intent> intents = intentCaptor.getAllValues(); + assertEquals(3, intents.size()); + Log.d(TAG, "captured intents: " + intents); + checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED); + checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED); + checkWifiStateChangedBroadcast(intents.get(2), WIFI_STATE_ENABLED, WIFI_STATE_ENABLING); + + checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED); + verify(mScanRequestProxy, atLeastOnce()).enableScanningForHiddenNetworks(true); + } + + private void checkWifiScanStateChangedBroadcast(Intent intent, int expectedCurrentState) { + String action = intent.getAction(); + assertEquals(WIFI_SCAN_AVAILABLE, action); + int currentState = intent.getIntExtra(EXTRA_SCAN_AVAILABLE, WIFI_STATE_UNKNOWN); + assertEquals(expectedCurrentState, currentState); + } + + private void checkWifiStateChangedBroadcast( + Intent intent, int expectedCurrentState, int expectedPrevState) { + String action = intent.getAction(); + assertEquals(WIFI_STATE_CHANGED_ACTION, action); + int currentState = intent.getIntExtra(EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN); + assertEquals(expectedCurrentState, currentState); + int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_STATE, WIFI_STATE_UNKNOWN); + assertEquals(expectedPrevState, prevState); + } + + + private void checkWifiStateChangeListenerUpdate(int expectedCurrentState) { + verify(mListener).onStateChanged(eq(expectedCurrentState)); + } + + private void verifyNotificationsForCleanShutdown(int fromState) { + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext, atLeastOnce()) + .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL)); + + List<Intent> intents = intentCaptor.getAllValues(); + assertEquals(3, intents.size()); + checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, fromState); + checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED); + checkWifiStateChangedBroadcast(intents.get(2), WIFI_STATE_DISABLED, WIFI_STATE_DISABLING); + verify(mScanRequestProxy).enableScanningForHiddenNetworks(false); + verify(mScanRequestProxy).clearScanResults(); + } + + private void verifyNotificationsForFailure() { + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext, atLeastOnce()) + .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL)); + + List<Intent> intents = intentCaptor.getAllValues(); + assertEquals(3, intents.size()); + checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, WIFI_STATE_ENABLED); + checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED); + checkWifiStateChangedBroadcast(intents.get(2), WIFI_STATE_DISABLED, WIFI_STATE_DISABLING); + checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED); + verify(mScanRequestProxy).enableScanningForHiddenNetworks(false); + verify(mScanRequestProxy).clearScanResults(); + } + + /** + * ClientMode start sets up an interface in ClientMode. + */ + @Test + public void clientModeStartCreatesClientInterface() throws Exception { + startClientModeAndVerifyEnabled(); + } + + /** + * ClientMode increments failure metrics when failing to setup client mode. + */ + @Test + public void detectAndReportErrorWhenSetupForClientWifiNativeFailure() throws Exception { + when(mWifiNative.setupInterfaceForClientMode(eq(false), any())).thenReturn(null); + mClientModeManager.start(); + mLooper.dispatchAll(); + + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), + eq(UserHandle.ALL)); + checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED); + checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN); + } + + /** + * ClientMode start does not indicate scanning is available when the interface name is empty. + */ + @Test + public void clientModeStartDoesNotSendScanningActiveWhenClientInterfaceNameIsEmpty() + throws Exception { + when(mWifiNative.setupInterfaceForClientMode(eq(false), any())).thenReturn(""); + mClientModeManager.start(); + mLooper.dispatchAll(); + + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), + eq(UserHandle.ALL)); + + List<Intent> intents = intentCaptor.getAllValues(); + assertEquals(2, intents.size()); + checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED); + checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED); + checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN); + } + + /** + * Calling ClientModeManager.start twice does not crash or restart client mode. + */ + @Test + public void clientModeStartCalledTwice() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mWifiNative, mContext); + mClientModeManager.start(); + mLooper.dispatchAll(); + verifyNoMoreInteractions(mWifiNative, mContext); + } + + /** + * ClientMode stop properly cleans up state + */ + @Test + public void clientModeStopCleansUpState() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext); + mClientModeManager.stop(); + mLooper.dispatchAll(); + + verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED); + } + + /** + * Calling stop when ClientMode is not started should not send scan state updates + */ + @Test + public void clientModeStopWhenNotStartedDoesNotUpdateScanStateUpdates() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext); + mClientModeManager.stop(); + mLooper.dispatchAll(); + verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED); + + reset(mContext, mListener); + // now call stop again + mClientModeManager.stop(); + mLooper.dispatchAll(); + verify(mContext, never()).sendStickyBroadcastAsUser(any(), any()); + verify(mListener, never()).onStateChanged(anyInt()); + } + + /** + * Triggering interface down when ClientMode is active properly exits the active state. + */ + @Test + public void clientModeStartedStopsWhenInterfaceDown() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext, mScanRequestProxy); + mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME); + mLooper.dispatchAll(); + verifyNotificationsForFailure(); + } + + /** + * Testing the handling of a wifinative failure status change notification. + */ + @Test + public void clientModeStartedStopsOnNativeFailure() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext, mScanRequestProxy, mListener); + mStatusListenerCaptor.getValue().onStatusChanged(false); + mLooper.dispatchNext(); + + checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN); + + mLooper.dispatchAll(); + + verifyNotificationsForFailure(); + } + + /** + * Testing that handling of a wifinative callback that is not a failuer does not stop client + * mode. + */ + @Test + public void clientModeStartedAndStaysUpOnNativeNonFailureCallback() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext, mScanRequestProxy, mListener); + mStatusListenerCaptor.getValue().onStatusChanged(true); + mLooper.dispatchAll(); + + verify(mListener, never()).onStateChanged(eq(WIFI_STATE_UNKNOWN)); + verify(mListener, never()).onStateChanged(eq(WIFI_STATE_DISABLING)); + verify(mListener, never()).onStateChanged(eq(WIFI_STATE_DISABLED)); + } + + + /** + * Testing the handling of an interface destroyed notification. + */ + @Test + public void clientModeStartedStopsOnInterfaceDestroyed() throws Exception { + startClientModeAndVerifyEnabled(); + reset(mContext, mScanRequestProxy, mListener); + + mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME); + mLooper.dispatchAll(); + verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED); + } +} |