diff options
author | David Su <dysu@google.com> | 2019-09-19 16:44:21 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-09-19 16:44:21 +0000 |
commit | 740ed6892a15dafea822f70ab1c28fc5d42fe1e8 (patch) | |
tree | 4d93de183275805d2e40df118371641c1118b7b2 /tests | |
parent | 2c3e6f177642a3dcd378e0a404d60ba2af2841ed (diff) | |
parent | 8f627f09003a7d73a674e2c15235eda668cfce06 (diff) |
Merge changes from topic "sta-plus-sta-boot-time-regression"
* changes:
Fix boot time regression
Revert "Revert WifiController/ActiveModeWarden refactor due to boot time regression"
Diffstat (limited to 'tests')
7 files changed, 1563 insertions, 1391 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java index e0de06254..f5c5428d9 100644 --- a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java @@ -20,11 +20,16 @@ import static com.android.server.wifi.ActiveModeManager.SCAN_NONE; import static com.android.server.wifi.ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS; import static com.android.server.wifi.ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.*; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Resources; +import android.location.LocationManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.BatteryStats; @@ -33,7 +38,9 @@ import android.util.Log; import androidx.test.filters.SmallTest; +import com.android.internal.R; import com.android.internal.app.IBatteryStats; +import com.android.server.wifi.util.WifiPermissionsUtil; import org.junit.After; import org.junit.Before; @@ -46,6 +53,9 @@ import org.mockito.stubbing.Answer; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; /** * Unit tests for {@link com.android.server.wifi.ActiveModeWarden}. @@ -54,17 +64,19 @@ import java.io.PrintWriter; public class ActiveModeWardenTest extends WifiBaseTest { public static final String TAG = "WifiActiveModeWardenTest"; - private static final String CLIENT_MODE_STATE_STRING = "ClientModeActiveState"; - private static final String SCAN_ONLY_MODE_STATE_STRING = "ScanOnlyModeActiveState"; - private static final String WIFI_DISABLED_STATE_STRING = "WifiDisabledState"; + private static final String CLIENT_MODE_STATE_STRING = "StaEnabledState"; + private static final String SCAN_ONLY_MODE_STATE_STRING = "StaDisabledWithScanState"; + private static final String STA_DISABLED_STATE_STRING = "StaDisabledState"; + private static final String WIFI_IFACE_NAME = "mockWlan"; + private static final int TEST_WIFI_RECOVERY_DELAY_MS = 2000; + TestLooper mLooper; @Mock WifiInjector mWifiInjector; @Mock Context mContext; @Mock Resources mResources; @Mock WifiNative mWifiNative; @Mock WifiApConfigStore mWifiApConfigStore; - TestLooper mLooper; @Mock ClientModeManager mClientModeManager; @Mock ScanOnlyModeManager mScanOnlyModeManager; @Mock SoftApManager mSoftApManager; @@ -73,11 +85,15 @@ public class ActiveModeWardenTest extends WifiBaseTest { @Mock SelfRecovery mSelfRecovery; @Mock BaseWifiDiagnostics mWifiDiagnostics; @Mock ScanRequestProxy mScanRequestProxy; + @Mock ClientModeImpl mClientModeImpl; + @Mock FrameworkFacade mFacade; + @Mock WifiSettingsStore mSettingsStore; + @Mock WifiPermissionsUtil mWifiPermissionsUtil; + ClientModeManager.Listener mClientListener; ScanOnlyModeManager.Listener mScanOnlyListener; - ScanOnlyModeCallback mScanOnlyCallback = new ScanOnlyModeCallback(); - ClientModeCallback mClientModeCallback = new ClientModeCallback(); WifiManager.SoftApCallback mSoftApManagerCallback; + SoftApModeConfiguration mSoftApConfig; @Mock WifiManager.SoftApCallback mSoftApStateMachineCallback; @Mock WifiManager.SoftApCallback mLohsStateMachineCallback; WifiNative.StatusListener mWifiNativeStatusListener; @@ -96,19 +112,47 @@ public class ActiveModeWardenTest extends WifiBaseTest { MockitoAnnotations.initMocks(this); mLooper = new TestLooper(); - when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); - when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics); when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy); when(mClientModeManager.getScanMode()).thenReturn(SCAN_WITH_HIDDEN_NETWORKS); when(mContext.getResources()).thenReturn(mResources); when(mScanOnlyModeManager.getScanMode()).thenReturn(SCAN_WITHOUT_HIDDEN_NETWORKS); when(mSoftApManager.getScanMode()).thenReturn(SCAN_NONE); - when(mResources.getString( - eq(com.android.internal.R.string.wifi_localhotspot_configure_ssid_default))) + when(mResources.getString(R.string.wifi_localhotspot_configure_ssid_default)) .thenReturn("AndroidShare"); + when(mResources.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay)) + .thenReturn(TEST_WIFI_RECOVERY_DELAY_MS); + + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + + doAnswer(new Answer<ClientModeManager>() { + public ClientModeManager answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + mClientListener = (ClientModeManager.Listener) args[0]; + return mClientModeManager; + } + }).when(mWifiInjector).makeClientModeManager(any(ClientModeManager.Listener.class)); + doAnswer(new Answer<ScanOnlyModeManager>() { + public ScanOnlyModeManager answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + mScanOnlyListener = (ScanOnlyModeManager.Listener) args[0]; + return mScanOnlyModeManager; + } + }).when(mWifiInjector).makeScanOnlyModeManager(any(ScanOnlyModeManager.Listener.class)); + doAnswer(new Answer<SoftApManager>() { + public SoftApManager answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + mSoftApManagerCallback = (WifiManager.SoftApCallback) args[0]; + mSoftApConfig = (SoftApModeConfiguration) args[1]; + return mSoftApManager; + } + }).when(mWifiInjector).makeSoftApManager(any(WifiManager.SoftApCallback.class), any()); mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); mLooper.dispatchAll(); verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture()); @@ -116,17 +160,25 @@ public class ActiveModeWardenTest extends WifiBaseTest { mActiveModeWarden.registerSoftApCallback(mSoftApStateMachineCallback); mActiveModeWarden.registerLohsCallback(mLohsStateMachineCallback); - mActiveModeWarden.registerScanOnlyCallback(mScanOnlyCallback); - mActiveModeWarden.registerClientModeCallback(mClientModeCallback); } private ActiveModeWarden createActiveModeWarden() { - return new ActiveModeWarden(mWifiInjector, - mContext, - mLooper.getLooper(), - mWifiNative, - mDefaultModeManager, - mBatteryStats); + ActiveModeWarden warden = new ActiveModeWarden( + mWifiInjector, + mLooper.getLooper(), + mWifiNative, + mDefaultModeManager, + mBatteryStats, + mWifiDiagnostics, + mContext, + mClientModeImpl, + mSettingsStore, + mFacade, + mWifiPermissionsUtil); + // SelfRecovery is created in WifiInjector after ActiveModeWarden, so getSelfRecovery() + // returns null when constructing ActiveModeWarden. + when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); + return warden; } /** @@ -135,29 +187,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { @After public void cleanUp() throws Exception { mActiveModeWarden = null; - } - - private class ClientModeCallback implements ClientModeManager.Listener { - public int currentState = WifiManager.WIFI_STATE_UNKNOWN; - - @Override - public void onStateChanged(int state) { - currentState = state; - } - } - - private class ScanOnlyModeCallback implements ScanOnlyModeManager.Listener { - public int currentState = WifiManager.WIFI_STATE_UNKNOWN; - - @Override - public void onStateChanged(int state) { - currentState = state; - } - } - - private void enterSoftApActiveMode() throws Exception { - enterSoftApActiveMode( - new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); + mLooper.dispatchAll(); } /** @@ -165,21 +195,13 @@ public class ActiveModeWardenTest extends WifiBaseTest { */ private void enterClientModeActiveState() throws Exception { String fromState = mActiveModeWarden.getCurrentMode(); - doAnswer( - new Answer<Object>() { - public ClientModeManager answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - mClientListener = (ClientModeManager.Listener) args[0]; - return mClientModeManager; - } - }).when(mWifiInjector).makeClientModeManager( - any(ClientModeManager.Listener.class)); - mActiveModeWarden.enterClientMode(); + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + mActiveModeWarden.wifiToggled(); mLooper.dispatchAll(); mClientListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED); mLooper.dispatchAll(); - assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInClientState(); verify(mClientModeManager).start(); if (fromState.equals(SCAN_ONLY_MODE_STATE_STRING)) { verify(mScanRequestProxy).enableScanning(false, false); @@ -193,28 +215,27 @@ public class ActiveModeWardenTest extends WifiBaseTest { */ private void enterScanOnlyModeActiveState() throws Exception { String fromState = mActiveModeWarden.getCurrentMode(); - doAnswer( - new Answer<Object>() { - public ScanOnlyModeManager answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - mScanOnlyListener = (ScanOnlyModeManager.Listener) args[0]; - return mScanOnlyModeManager; - } - }).when(mWifiInjector).makeScanOnlyModeManager( - any(ScanOnlyModeManager.Listener.class)); - mActiveModeWarden.enterScanOnlyMode(); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + mActiveModeWarden.wifiToggled(); mLooper.dispatchAll(); mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED); mLooper.dispatchAll(); - assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInScanOnlyState(); verify(mScanOnlyModeManager).start(); if (fromState.equals(CLIENT_MODE_STATE_STRING)) { verify(mScanRequestProxy).enableScanning(false, false); } verify(mScanRequestProxy).enableScanning(true, false); verify(mBatteryStats).noteWifiOn(); - verify(mBatteryStats).noteWifiState(eq(BatteryStats.WIFI_STATE_OFF_SCANNING), eq(null)); + verify(mBatteryStats).noteWifiState(BatteryStats.WIFI_STATE_OFF_SCANNING, null); + } + + private void enterSoftApActiveMode() throws Exception { + enterSoftApActiveMode( + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); } /** @@ -224,20 +245,11 @@ public class ActiveModeWardenTest extends WifiBaseTest { */ private void enterSoftApActiveMode(SoftApModeConfiguration softApConfig) throws Exception { String fromState = mActiveModeWarden.getCurrentMode(); - doAnswer( - new Answer<Object>() { - public SoftApManager answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - mSoftApManagerCallback = (WifiManager.SoftApCallback) args[0]; - assertEquals(softApConfig, (SoftApModeConfiguration) args[1]); - return mSoftApManager; - } - }).when(mWifiInjector).makeSoftApManager(any(WifiManager.SoftApCallback.class), - any()); - mActiveModeWarden.enterSoftAPMode(softApConfig); + mActiveModeWarden.startSoftAp(softApConfig); mLooper.dispatchAll(); + assertThat(softApConfig).isEqualTo(mSoftApConfig); verify(mSoftApManager).start(); - if (fromState.equals(WIFI_DISABLED_STATE_STRING)) { + if (fromState.equals(STA_DISABLED_STATE_STRING)) { verify(mBatteryStats).noteWifiOn(); } else if (!fromState.equals(SCAN_ONLY_MODE_STATE_STRING) && !fromState.equals(CLIENT_MODE_STATE_STRING)) { @@ -245,12 +257,156 @@ public class ActiveModeWardenTest extends WifiBaseTest { } } + private void enterStaDisabledState() { + String fromState = mActiveModeWarden.getCurrentMode(); + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + mActiveModeWarden.wifiToggled(); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + if (fromState.equals(SCAN_ONLY_MODE_STATE_STRING) + || fromState.equals(CLIENT_MODE_STATE_STRING)) { + verify(mScanRequestProxy).enableScanning(false, false); + } + } + + private void shutdownWifi() { + mActiveModeWarden.recoveryDisableWifi(); + mLooper.dispatchAll(); + } + + private void assertInScanOnlyState() { + assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(SCAN_ONLY_MODE_STATE_STRING); + } + + private void assertInClientState() { + assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(CLIENT_MODE_STATE_STRING); + } + + private void assertInStaDisabledState() { + assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(STA_DISABLED_STATE_STRING); + } + + /** + * Emergency mode is a sub-mode within each main state (ScanOnly, Client, StaDisabled). + */ + private void assertInEmergencyMode() { + assertThat(mActiveModeWarden.isInEmergencyMode()).isTrue(); + } + + /** + * Counts the number of times a void method was called on a mock. + * + * Void methods cannot be passed to Mockito.mockingDetails(). Thus we have to use method name + * matching instead. + */ + private static int getMethodInvocationCount(Object mock, String methodName) { + long count = mockingDetails(mock).getInvocations() + .stream() + .filter(invocation -> methodName.equals(invocation.getMethod().getName())) + .count(); + return (int) count; + } + + /** + * Counts the number of times a non-void method was called on a mock. + * + * For non-void methods, can pass the method call literal directly: + * e.g. getMethodInvocationCount(mock.method()); + */ + private static int getMethodInvocationCount(Object mockMethod) { + return mockingDetails(mockMethod).getInvocations().size(); + } + + private void assertWifiShutDown(Runnable r) { + assertWifiShutDown(r, 1); + } + + /** + * Asserts that the runnable r has shut down wifi properly. + * @param r runnable that will shut down wifi + * @param times expected number of times that <code>r</code> shut down wifi + */ + private void assertWifiShutDown(Runnable r, int times) { + // take snapshot of ActiveModeManagers + Collection<ActiveModeManager> activeModeManagers = + mActiveModeWarden.getActiveModeManagers(); + + List<Integer> expectedStopInvocationCounts = activeModeManagers + .stream() + .map(manager -> getMethodInvocationCount(manager, "stop") + times) + .collect(Collectors.toList()); + + r.run(); + + List<Integer> actualStopInvocationCounts = activeModeManagers + .stream() + .map(manager -> getMethodInvocationCount(manager, "stop")) + .collect(Collectors.toList()); + + String managerNames = activeModeManagers.stream() + .map(manager -> manager.getClass().getCanonicalName()) + .collect(Collectors.joining(", ", "[", "]")); + + assertThat(actualStopInvocationCounts) + .named(managerNames) + .isEqualTo(expectedStopInvocationCounts); + } + + private void assertEnteredEcmMode(Runnable r) { + assertEnteredEcmMode(r, 1); + } + /** - * Test that after starting up, ActiveModeWarden is in the Disabled State. + * Asserts that the runnable r has entered ECM state properly. + * @param r runnable that will enter ECM + * @param times expected number of times that <code>r</code> shut down wifi */ + private void assertEnteredEcmMode(Runnable r, int times) { + // take snapshot of ActiveModeManagers + Collection<ActiveModeManager> activeModeManagers = + mActiveModeWarden.getActiveModeManagers(); + + boolean disableWifiInEcm = mFacade.getConfigWiFiDisableInECBM(mContext); + + List<Integer> expectedStopInvocationCounts = activeModeManagers.stream() + .map(manager -> { + int initialCount = getMethodInvocationCount(manager, "stop"); + // carrier config enabled, all mode managers should have been shut down once + int count = disableWifiInEcm ? initialCount + times : initialCount; + if (manager instanceof SoftApManager) { + // expect SoftApManager.close() to be called + return count + times; + } else { + // don't expect other Managers close() to be called + return count; + } + }) + .collect(Collectors.toList()); + + r.run(); + + assertInEmergencyMode(); + + List<Integer> actualStopInvocationCounts = activeModeManagers.stream() + .map(manager -> getMethodInvocationCount(manager, "stop")) + .collect(Collectors.toList()); + + String managerNames = activeModeManagers.stream() + .map(manager -> manager.getClass().getCanonicalName()) + .collect(Collectors.joining(", ", "[", "]")); + + assertThat(actualStopInvocationCounts) + .named(managerNames) + .isEqualTo(expectedStopInvocationCounts); + } + + /** Test that after starting up, ActiveModeWarden is in the Disabled State. */ @Test - public void testWifiDisabledAtStartup() throws Exception { - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + public void testWifiDisabledAtStartup() { + assertInStaDisabledState(); } /** @@ -277,8 +433,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { @Test public void testEnterSoftApModeFromDifferentState() throws Exception { enterClientModeActiveState(); - mLooper.dispatchAll(); - assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInClientState(); reset(mBatteryStats, mScanRequestProxy); enterSoftApActiveMode(); } @@ -290,11 +445,13 @@ public class ActiveModeWardenTest extends WifiBaseTest { public void testDisableWifiFromScanOnlyModeActiveState() throws Exception { enterScanOnlyModeActiveState(); - mActiveModeWarden.disableWifi(); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + mActiveModeWarden.scanAlwaysModeChanged(); mLooper.dispatchAll(); + verify(mScanOnlyModeManager).stop(); verify(mBatteryStats).noteWifiOff(); - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInStaDisabledState(); } /** @@ -305,11 +462,10 @@ public class ActiveModeWardenTest extends WifiBaseTest { enterSoftApActiveMode(); reset(mDefaultModeManager); - mActiveModeWarden.disableWifi(); - mLooper.dispatchAll(); + enterStaDisabledState(); verify(mSoftApManager, never()).stop(); verify(mBatteryStats, never()).noteWifiOff(); - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInStaDisabledState(); } /** @@ -324,7 +480,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { enterClientModeActiveState(); mLooper.dispatchAll(); verify(mScanOnlyModeManager).stop(); - assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInClientState(); } /** @@ -334,7 +490,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { public void testReenterClientModeActiveStateIsNop() throws Exception { enterClientModeActiveState(); reset(mClientModeManager); - mActiveModeWarden.enterClientMode(); + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + mActiveModeWarden.wifiToggled(); mLooper.dispatchAll(); verify(mClientModeManager, never()).start(); } @@ -352,7 +509,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { enterClientModeActiveState(); mLooper.dispatchAll(); verify(mSoftApManager, never()).stop(); - assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInClientState(); verify(mWifiNative, never()).teardownAllInterfaces(); } @@ -368,7 +525,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { // now inject failure through the SoftApManager.Listener mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0); mLooper.dispatchAll(); - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInStaDisabledState(); // clear the first call to start SoftApManager reset(mSoftApManager, mBatteryStats); @@ -386,10 +543,9 @@ public class ActiveModeWardenTest extends WifiBaseTest { // now inject a failure through the ScanOnlyModeManager.Listener mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN); mLooper.dispatchAll(); - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInStaDisabledState(); verify(mScanOnlyModeManager).stop(); verify(mBatteryStats).noteWifiOff(); - assertEquals(WifiManager.WIFI_STATE_UNKNOWN, mScanOnlyCallback.currentState); } /** @@ -414,10 +570,12 @@ public class ActiveModeWardenTest extends WifiBaseTest { @Test public void testScanOnlyModeDisabledWhenActive() throws Exception { enterScanOnlyModeActiveState(); + // now inject the stop message through the ScanOnlyModeManager.Listener mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); mLooper.dispatchAll(); - assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode()); + + assertInStaDisabledState(); verify(mScanOnlyModeManager).stop(); verify(mBatteryStats).noteWifiOff(); } @@ -526,7 +684,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { // now inject failure through the SoftApManager.Listener mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED); mLooper.dispatchAll(); - assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInScanOnlyState(); verify(mScanOnlyModeManager, never()).stop(); } @@ -540,7 +698,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { // now inject failure through the SoftApManager.Listener mScanOnlyListener.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING); mLooper.dispatchAll(); - assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode()); + assertInScanOnlyState(); verify(mScanOnlyModeManager, never()).stop(); } @@ -598,8 +756,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { eq(softApConfig2))) .thenReturn(softapManager); - mActiveModeWarden.enterSoftAPMode(softApConfig1); - mActiveModeWarden.enterSoftAPMode(softApConfig2); + mActiveModeWarden.startSoftAp(softApConfig1); + mActiveModeWarden.startSoftAp(softApConfig2); mLooper.dispatchAll(); verify(mSoftApManager).start(); verify(softapManager).start(); @@ -613,7 +771,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { */ @Test public void disableWifiWhenAlreadyOff() throws Exception { - mActiveModeWarden.disableWifi(); + enterStaDisabledState(); + verifyZeroInteractions(mWifiNative); } /** @@ -650,9 +809,9 @@ public class ActiveModeWardenTest extends WifiBaseTest { mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); mLooper.dispatchAll(); - mActiveModeWarden.shutdownWifi(); + shutdownWifi(); - assertEquals(WifiManager.WIFI_STATE_DISABLED, mClientModeCallback.currentState); + assertInStaDisabledState(); } /** @@ -662,12 +821,12 @@ public class ActiveModeWardenTest extends WifiBaseTest { public void onDestroyedCallbackDoesNotCrashWhenClientModeAlreadyStopped() throws Exception { enterClientModeActiveState(); - mActiveModeWarden.shutdownWifi(); + shutdownWifi(); mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); mLooper.dispatchAll(); - assertEquals(WifiManager.WIFI_STATE_DISABLED, mClientModeCallback.currentState); + assertInStaDisabledState(); } /** @@ -680,7 +839,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0); mLooper.dispatchAll(); - mActiveModeWarden.shutdownWifi(); + shutdownWifi(); verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0); } @@ -692,7 +851,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { public void onDestroyedCallbackDoesNotCrashWhenSoftApModeAlreadyStopped() throws Exception { enterSoftApActiveMode(); - mActiveModeWarden.shutdownWifi(); + shutdownWifi(); mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0); mLooper.dispatchAll(); @@ -724,10 +883,10 @@ public class ActiveModeWardenTest extends WifiBaseTest { PrintWriter writer = new PrintWriter(stream); mActiveModeWarden.dump(null, writer, null); - verify(mSoftApManager).dump(eq(null), eq(writer), eq(null)); + verify(mSoftApManager).dump(null, writer, null); // can only be in scan or client, so we should not have a client mode active - verify(mClientModeManager, never()).dump(eq(null), eq(writer), eq(null)); - verify(mScanOnlyModeManager).dump(eq(null), eq(writer), eq(null)); + verify(mClientModeManager, never()).dump(null, writer, null); + verify(mScanOnlyModeManager).dump(null, writer, null); } /** @@ -756,17 +915,1033 @@ public class ActiveModeWardenTest extends WifiBaseTest { .thenReturn(lohsSoftapManager); // enable tethering and LOHS - mActiveModeWarden.enterSoftAPMode(tetherConfig); - mActiveModeWarden.enterSoftAPMode(lohsConfig); + mActiveModeWarden.startSoftAp(tetherConfig); + mActiveModeWarden.startSoftAp(lohsConfig); mLooper.dispatchAll(); verify(mSoftApManager).start(); verify(lohsSoftapManager).start(); verify(mBatteryStats).noteWifiOn(); // disable tethering - mActiveModeWarden.stopSoftAPMode(WifiManager.IFACE_IP_MODE_TETHERED); + mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); verify(mSoftApManager).stop(); verify(lohsSoftapManager, never()).stop(); } + + /** + * Verify that toggling wifi from disabled starts client mode. + */ + @Test + public void enableWifi() throws Exception { + assertInStaDisabledState(); + + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + mActiveModeWarden.wifiToggled(); + mLooper.dispatchAll(); + + assertInClientState(); + } + + /** + * Test verifying that we can enter scan mode when the scan mode changes + */ + @Test + public void enableScanMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + verify(mScanOnlyModeManager).start(); + assertInScanOnlyState(); + verify(mScanOnlyModeManager, never()).stop(); + } + + /** + * Verify that if scanning is enabled at startup, we enter scan mode + */ + @Test + public void testEnterScanModeAtStartWhenSet() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + } + + /** + * Do not enter scan mode if location mode disabled. + */ + @Test + public void testDoesNotEnterScanModeWhenLocationModeDisabled() throws Exception { + // Start a new WifiController with wifi disabled + when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); + + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + + // toggling scan always available is not sufficient for scan mode + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + } + + /** + * Only enter scan mode if location mode enabled + */ + @Test + public void testEnterScanModeWhenLocationModeEnabled() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); + + reset(mContext); + when(mContext.getResources()).thenReturn(mResources); + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + + ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class)); + BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); + + assertInStaDisabledState(); + + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); + broadcastReceiver.onReceive(mContext, intent); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + } + + + /** + * Disabling location mode when in scan mode will disable wifi + */ + @Test + public void testExitScanModeWhenLocationModeDisabled() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + + reset(mContext); + when(mContext.getResources()).thenReturn(mResources); + mActiveModeWarden = createActiveModeWarden(); + mActiveModeWarden.start(); + mLooper.dispatchAll(); + + ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class)); + BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); + + assertInScanOnlyState(); + + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); + Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); + broadcastReceiver.onReceive(mContext, intent); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + } + + /** + * When in Client mode, make sure ECM triggers wifi shutdown. + */ + @Test + public void testEcmOnFromClientMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + enableWifi(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * ECM disabling messages, when in client mode (not expected) do not trigger state changes. + */ + @Test + public void testEcmOffInClientMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); + enableWifi(); + + // Test with WifiDisableInECBM turned off + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); + + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * When ECM activates and we are in client mode, disabling ECM should return us to client mode. + */ + @Test + public void testEcmDisabledReturnsToClientMode() throws Exception { + enableWifi(); + assertInClientState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + assertInClientState(); + } + + /** + * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed + * update. + */ + @Test + public void testEcmOnFromScanMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * When Ecm mode is disabled, we should not shut down scan mode if we get an emergency mode + * changed update, but we should turn off soft AP + */ + @Test + public void testEcmOffInScanMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + + // Test with WifiDisableInECBM turned off: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); + + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * When ECM is disabled, we should return to scan mode + */ + @Test + public void testEcmDisabledReturnsToScanMode() throws Exception { + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + } + + /** + * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed + * update. + */ + @Test + public void testEcmOnFromSoftApMode() throws Exception { + enterSoftApActiveMode(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + /** + * When Ecm mode is disabled, we should shut down softap mode if we get an emergency mode + * changed update + */ + @Test + public void testEcmOffInSoftApMode() throws Exception { + enterSoftApActiveMode(); + + // Test with WifiDisableInECBM turned off: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); + + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + + verify(mSoftApManager).stop(); + } + + /** + * When ECM is activated and we were in softap mode, we should just return to wifi off when ECM + * ends + */ + @Test + public void testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn() throws Exception { + assertInStaDisabledState(); + + enterSoftApActiveMode(); + + // verify Soft AP Manager started + verify(mSoftApManager).start(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + + // verify no additional calls to enable softap + verify(mSoftApManager).start(); + } + + /** + * Wifi should remain off when already disabled and we enter ECM. + */ + @Test + public void testEcmOnFromDisabledMode() throws Exception { + assertInStaDisabledState(); + verify(mSoftApManager, never()).start(); + verify(mClientModeManager, never()).start(); + verify(mScanOnlyModeManager, never()).start(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + } + + + /** + * Updates about call state change also trigger entry of ECM mode. + */ + @Test + public void testEnterEcmOnEmergencyCallStateChange() throws Exception { + assertInStaDisabledState(); + + enableWifi(); + assertInClientState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + // test call state changed + mActiveModeWarden.emergencyCallStateChanged(true); + mLooper.dispatchAll(); + }); + + mActiveModeWarden.emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + assertInClientState(); + } + + /** + * Verify when both ECM and call state changes arrive, we enter ECM mode + */ + @Test + public void testEnterEcmWithBothSignals() throws Exception { + assertInStaDisabledState(); + + enableWifi(); + assertInClientState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertWifiShutDown(() -> { + mActiveModeWarden.emergencyCallStateChanged(true); + mLooper.dispatchAll(); + }); + + assertWifiShutDown(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }, 0); // does not cause another shutdown + + // client mode only started once so far + verify(mClientModeManager).start(); + + mActiveModeWarden.emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + // stay in ecm, do not send an additional client mode trigger + assertInEmergencyMode(); + // assert that the underlying state is still client state + assertInClientState(); + // client mode still only started once + verify(mClientModeManager).start(); + + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + // now we can re-enable wifi + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * Verify when both ECM and call state changes arrive but out of order, we enter ECM mode + */ + @Test + public void testEnterEcmWithBothSignalsOutOfOrder() throws Exception { + assertInStaDisabledState(); + + enableWifi(); + + assertInClientState(); + verify(mClientModeManager).start(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + assertInClientState(); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallStateChanged(true); + mLooper.dispatchAll(); + }, 0); // does not enter ECM state again + + mActiveModeWarden.emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + // stay in ecm, do not send an additional client mode trigger + verify(mClientModeManager).start(); + assertInClientState(); + + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + // now we can re-enable wifi + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * Verify when both ECM and call state changes arrive but completely out of order, + * we still enter and properly exit ECM mode + */ + @Test + public void testEnterEcmWithBothSignalsOppositeOrder() throws Exception { + assertInStaDisabledState(); + + enableWifi(); + + assertInClientState(); + verify(mClientModeManager).start(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallStateChanged(true); + mLooper.dispatchAll(); + }); + assertInClientState(); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }, 0); // still only 1 shutdown + + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + // stay in ecm, do not send an additional client mode trigger + verify(mClientModeManager).start(); + assertInClientState(); + + mActiveModeWarden.emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + // now we can re-enable wifi + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * When ECM is active, we might get addition signals of ECM mode, drop those additional signals, + * we must exit when one of each signal is received. + * + * In any case, duplicate signals indicate a bug from Telephony. Each signal should be turned + * off before it is turned on again. + */ + @Test + public void testProperExitFromEcmModeWithMultipleMessages() throws Exception { + assertInStaDisabledState(); + + enableWifi(); + + verify(mClientModeManager).start(); + assertInClientState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mActiveModeWarden.emergencyCallStateChanged(true); + mActiveModeWarden.emergencyCallStateChanged(true); + mActiveModeWarden.emergencyCallbackModeChanged(true); + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + assertInClientState(); + + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + }, 0); + + // didn't enter client mode again + verify(mClientModeManager).start(); + assertInClientState(); + + // now we will exit ECM + mActiveModeWarden.emergencyCallStateChanged(false); + mLooper.dispatchAll(); + + // now we can re-enable wifi + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * Toggling wifi when in ECM does not exit ecm mode and enable wifi + */ + @Test + public void testWifiDoesNotToggleOnWhenInEcm() throws Exception { + assertInStaDisabledState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + // test ecm changed + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + // now toggle wifi and verify we do not start wifi + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + mActiveModeWarden.wifiToggled(); + mLooper.dispatchAll(); + + verify(mClientModeManager, never()).start(); + assertInStaDisabledState(); + } + + @Test + public void testAirplaneModeDoesNotToggleOnWhenInEcm() throws Exception { + // TODO(b/139829963): investigate the expected behavior is when toggling airplane mode in + // ECM + } + + /** + * Toggling scan mode when in ECM does not exit ecm mode and enable scan mode + */ + @Test + public void testScanModeDoesNotToggleOnWhenInEcm() throws Exception { + assertInStaDisabledState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + // now enable scanning and verify we do not start wifi + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + verify(mScanOnlyModeManager, never()).start(); + assertInStaDisabledState(); + } + + + /** + * Toggling softap mode when in ECM does not exit ecm mode and enable softap + */ + @Test + public void testSoftApModeDoesNotToggleOnWhenInEcm() throws Exception { + assertInStaDisabledState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + mActiveModeWarden.startSoftAp( + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); + mLooper.dispatchAll(); + + verify(mSoftApManager, never()).start(); + assertInStaDisabledState(); + } + + /** + * Toggling off softap mode when in ECM does not induce a mode change + */ + @Test + public void testSoftApStoppedDoesNotSwitchModesWhenInEcm() throws Exception { + assertInStaDisabledState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + verifyNoMoreInteractions(mSoftApManager, mClientModeManager, mScanOnlyModeManager); + } + + /** + * Toggling softap mode when in airplane mode needs to enable softap + */ + @Test + public void testSoftApModeToggleWhenInAirplaneMode() throws Exception { + // Test with airplane mode turned on: + when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); + + // Turn on SoftAp. + mActiveModeWarden.startSoftAp( + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); + mLooper.dispatchAll(); + verify(mSoftApManager).start(); + + // Turn off SoftAp. + mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED); + mLooper.dispatchAll(); + + verify(mSoftApManager).stop(); + } + + /** + * Toggling off scan mode when in ECM does not induce a mode change + */ + @Test + public void testScanModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception { + enterScanOnlyModeActiveState(); + assertInScanOnlyState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + } + + /** + * Toggling off client mode when in ECM does not induce a mode change + */ + @Test + public void testClientModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception { + enterClientModeActiveState(); + assertInClientState(); + + // Test with WifiDisableInECBM turned on: + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + // test ecm changed + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + + mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); + mLooper.dispatchAll(); + + assertInClientState(); + } + + /** + * When AP mode is enabled and wifi was previously in AP mode, we should return to + * StaEnabledState after the AP is disabled. + * Enter StaEnabledState, activate AP mode, disable AP mode. + * <p> + * Expected: AP should successfully start and exit, then return to StaEnabledState. + */ + @Test + public void testReturnToStaEnabledStateAfterAPModeShutdown() throws Exception { + enableWifi(); + assertInClientState(); + verify(mClientModeManager).start(); + + mActiveModeWarden.startSoftAp( + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); + // add an "unexpected" sta mode stop to simulate a single interface device + mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED); + mLooper.dispatchAll(); + + when(mSettingsStore.getWifiSavedState()).thenReturn(1); + mActiveModeWarden.softApStopped(); + mLooper.dispatchAll(); + + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * When in STA mode and SoftAP is enabled and the device supports STA+AP (i.e. the STA wasn't + * shut down when the AP started), both modes will be running concurrently. + * + * Then when the AP is disabled, we should remain in STA mode. + * + * Enter StaEnabledState, activate AP mode, toggle WiFi off. + * <p> + * Expected: AP should successfully start and exit, then return to StaEnabledState. + */ + @Test + public void testReturnToStaEnabledStateAfterWifiEnabledShutdown() throws Exception { + enableWifi(); + assertInClientState(); + verify(mClientModeManager).start(); + + mActiveModeWarden.startSoftAp( + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null)); + mLooper.dispatchAll(); + + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); + mActiveModeWarden.wifiToggled(); + mActiveModeWarden.softApStopped(); + mLooper.dispatchAll(); + + // wasn't called again + verify(mClientModeManager).start(); + assertInClientState(); + } + + @Test + public void testRestartWifiStackInStaEnabledStateTriggersBugReport() throws Exception { + enableWifi(); + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + mLooper.dispatchAll(); + verify(mClientModeImpl).takeBugReport(anyString(), anyString()); + } + + @Test + public void testRestartWifiWatchdogDoesNotTriggerBugReport() throws Exception { + enableWifi(); + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + mLooper.dispatchAll(); + verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString()); + } + + /** + * When in sta mode, CMD_RECOVERY_DISABLE_WIFI messages should trigger wifi to disable. + */ + @Test + public void testRecoveryDisabledTurnsWifiOff() throws Exception { + enableWifi(); + assertInClientState(); + mActiveModeWarden.recoveryDisableWifi(); + mLooper.dispatchAll(); + verify(mClientModeManager).stop(); + assertInStaDisabledState(); + } + + /** + * When wifi is disabled, CMD_RECOVERY_DISABLE_WIFI should not trigger a state change. + */ + @Test + public void testRecoveryDisabledWhenWifiAlreadyOff() throws Exception { + assertInStaDisabledState(); + assertWifiShutDown(() -> { + mActiveModeWarden.recoveryDisableWifi(); + mLooper.dispatchAll(); + }); + } + + /** + * The command to trigger a WiFi reset should not trigger any action by WifiController if we + * are not in STA mode. + * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures + * should be ignored. + * Create and start WifiController in StaDisabledState, send command to restart WiFi + * <p> + * Expected: WiFiController should not call ActiveModeWarden.disableWifi() + */ + @Test + public void testRestartWifiStackInStaDisabledState() throws Exception { + assertInStaDisabledState(); + + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + verifyNoMoreInteractions(mScanOnlyModeManager, mClientModeManager, mSoftApManager); + } + + /** + * The command to trigger a WiFi reset should not trigger any action by WifiController if we + * are not in STA mode, even if scans are allowed. + * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures + * should be ignored. + * Create and start WifiController in StaDisabledState, send command to restart WiFi + * <p> + * Expected: WiFiController should not call ActiveModeWarden.disableWifi() or + * ActiveModeWarden.shutdownWifi(). + */ + @Test + public void testRestartWifiStackInStaDisabledWithScanState() throws Exception { + assertInStaDisabledState(); + + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + mActiveModeWarden.scanAlwaysModeChanged(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + verify(mScanOnlyModeManager).start(); + + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + mLooper.dispatchAll(); + + verify(mScanOnlyModeManager).stop(); + assertInStaDisabledState(); + + mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); + mLooper.dispatchAll(); + + verify(mScanOnlyModeManager, times(2)).start(); + assertInScanOnlyState(); + } + + /** + * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through + * the ActiveModeWarden.shutdownWifi() call when in STA mode. + * WiFi is in connect mode, calls to reset the wifi stack due to connection failures + * should trigger a supplicant stop, and subsequently, a driver reload. + * Create and start WifiController in StaEnabledState, send command to restart WiFi + * <p> + * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and + * ActiveModeWarden should enter CONNECT_MODE and the wifi driver should be started. + */ + @Test + public void testRestartWifiStackInStaEnabledState() throws Exception { + enableWifi(); + assertInClientState(); + verify(mClientModeManager).start(); + + assertWifiShutDown(() -> { + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + mLooper.dispatchAll(); + }); + + // still only started once + verify(mClientModeManager).start(); + + mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); + mLooper.dispatchAll(); + + // started again + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } + + /** + * The command to trigger a WiFi reset should not trigger a reset when in ECM mode. + * Enable wifi and enter ECM state, send command to restart wifi. + * <p> + * Expected: The command to trigger a wifi reset should be ignored and we should remain in ECM + * mode. + */ + @Test + public void testRestartWifiStackDoesNotExitECMMode() throws Exception { + enableWifi(); + assertInClientState(); + verify(mClientModeManager).start(); + + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallStateChanged(true); + mLooper.dispatchAll(); + }); + assertInClientState(); + verify(mClientModeManager).stop(); + + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + mLooper.dispatchAll(); + + verify(mClientModeManager).start(); // wasn't called again + assertInEmergencyMode(); + assertInClientState(); + verifyNoMoreInteractions(mScanOnlyModeManager, mClientModeManager, mSoftApManager); + } + + /** + * The command to trigger a WiFi reset should trigger a reset when in AP mode. + * Enter AP mode, send command to restart wifi. + * <p> + * Expected: The command to trigger a wifi reset should trigger wifi shutdown. + */ + @Test + public void testRestartWifiStackFullyStopsWifi() throws Exception { + mActiveModeWarden.startSoftAp(new SoftApModeConfiguration( + WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null)); + mLooper.dispatchAll(); + verify(mSoftApManager).start(); + + assertWifiShutDown(() -> { + mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_STA_IFACE_DOWN); + mLooper.dispatchAll(); + }); + } + + /** + * Tests that when Wifi is already disabled and another Wifi toggle command arrives, but we're + * in airplane mode, don't enter scan mode. + */ + @Test + public void staDisabled_toggleWifiOff_scanAvailable_airplaneModeOn_dontGoToScanMode() { + assertInStaDisabledState(); + + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); + + mActiveModeWarden.wifiToggled(); + mLooper.dispatchAll(); + + assertInStaDisabledState(); + verify(mScanOnlyModeManager, never()).start(); + } + + /** + * Tests that when Wifi is already disabled and another Wifi toggle command arrives, but we're + * not in airplane mode, enter scan mode. + */ + @Test + public void staDisabled_toggleWifiOff_scanAvailable_airplaneModeOff_goToScanMode() { + assertInStaDisabledState(); + + when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); + when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); + when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); + when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); + + mActiveModeWarden.wifiToggled(); + mLooper.dispatchAll(); + + assertInScanOnlyState(); + verify(mScanOnlyModeManager).start(); + } + + /** + * Tests that if the carrier config to disable Wifi is enabled during ECM, Wifi is shut down + * when entering ECM and turned back on when exiting ECM. + */ + @Test + public void ecmDisablesWifi_exitEcm_restartWifi() throws Exception { + enterClientModeActiveState(); + + verify(mClientModeManager).start(); + + when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); + assertEnteredEcmMode(() -> { + mActiveModeWarden.emergencyCallbackModeChanged(true); + mLooper.dispatchAll(); + }); + assertInClientState(); + verify(mClientModeManager).stop(); + + mActiveModeWarden.emergencyCallbackModeChanged(false); + mLooper.dispatchAll(); + + assertThat(mActiveModeWarden.isInEmergencyMode()).isFalse(); + // client mode restarted + verify(mClientModeManager, times(2)).start(); + assertInClientState(); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java b/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java index b2aef11d3..fe8bfd575 100644 --- a/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java @@ -31,43 +31,43 @@ import org.mockito.Mock; @SmallTest public class SelfRecoveryTest extends WifiBaseTest { SelfRecovery mSelfRecovery; - @Mock WifiController mWifiController; + @Mock ActiveModeWarden mActiveModeWarden; @Mock Clock mClock; @Before public void setUp() throws Exception { initMocks(this); - mSelfRecovery = new SelfRecovery(mWifiController, mClock); + mSelfRecovery = new SelfRecovery(mActiveModeWarden, mClock); } /** * Verifies that invocations of {@link SelfRecovery#trigger(int)} with valid reasons will send - * the restart message to {@link WifiController}. + * the restart message to {@link ActiveModeWarden}. */ @Test public void testValidTriggerReasonsSendMessageToWifiController() { mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + reset(mActiveModeWarden); when(mClock.getElapsedSinceBootMillis()) .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + reset(mActiveModeWarden); } /** * Verifies that invocations of {@link SelfRecovery#trigger(int)} with invalid reasons will not - * send the restart message to {@link WifiController}. + * send the restart message to {@link ActiveModeWarden}. */ @Test public void testInvalidTriggerReasonsDoesNotSendMessageToWifiController() { mSelfRecovery.trigger(-1); - verify(mWifiController, never()).sendMessage(anyInt(), anyString()); + verifyNoMoreInteractions(mActiveModeWarden); mSelfRecovery.trigger(8); - verify(mWifiController, never()).sendMessage(anyInt(), anyString()); + verifyNoMoreInteractions(mActiveModeWarden); } /** @@ -76,7 +76,7 @@ public class SelfRecoveryTest extends WifiBaseTest { @Test public void testStaIfaceDownDisablesWifi() { mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI)); + verify(mActiveModeWarden).recoveryDisableWifi(); } /** @@ -91,58 +91,53 @@ public class SelfRecoveryTest extends WifiBaseTest { // aren't ignored for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW / 2; i++) { mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + reset(mActiveModeWarden); mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + reset(mActiveModeWarden); } if ((SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW % 2) == 1) { mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + reset(mActiveModeWarden); } // Verify that further attempts to trigger restarts disable wifi mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyString()); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI)); - reset(mWifiController); + verify(mActiveModeWarden, never()) + .recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + verify(mActiveModeWarden).recoveryDisableWifi(); + reset(mActiveModeWarden); mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyString()); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI)); - reset(mWifiController); + verify(mActiveModeWarden, never()).recoveryRestartWifi(anyInt()); + verify(mActiveModeWarden).recoveryDisableWifi(); + reset(mActiveModeWarden); // Verify L.R.Watchdog can still restart things (It has its own complex limiter) mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + reset(mActiveModeWarden); // Verify Sta Interface Down will still disable wifi mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI)); - reset(mWifiController); + verify(mActiveModeWarden).recoveryDisableWifi(); + reset(mActiveModeWarden); // now TRAVEL FORWARDS IN TIME and ensure that more restarts can occur when(mClock.getElapsedSinceBootMillis()) .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + reset(mActiveModeWarden); when(mClock.getElapsedSinceBootMillis()) .thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1); mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE); + reset(mActiveModeWarden); } /** @@ -156,9 +151,8 @@ public class SelfRecoveryTest extends WifiBaseTest { for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) { // Verify L.R.Watchdog can still restart things (It has it's own complex limiter) mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), - anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG); + reset(mActiveModeWarden); } } @@ -172,10 +166,9 @@ public class SelfRecoveryTest extends WifiBaseTest { public void testTimeWindowLimiting_staIfaceDown_noEffect() { for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) { mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN); - verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI)); - verify(mWifiController, never()) - .sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt()); - reset(mWifiController); + verify(mActiveModeWarden).recoveryDisableWifi(); + verify(mActiveModeWarden, never()).recoveryRestartWifi(anyInt()); + reset(mActiveModeWarden); } } } diff --git a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java index d2127f733..5e13706f3 100644 --- a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java @@ -78,7 +78,7 @@ public class WakeupControllerTest extends WifiBaseTest { @Mock private FrameworkFacade mFrameworkFacade; @Mock private WifiSettingsStore mWifiSettingsStore; @Mock private WifiWakeMetrics mWifiWakeMetrics; - @Mock private WifiController mWifiController; + @Mock private ActiveModeWarden mActiveModeWarden; @Mock private WifiNative mWifiNative; @Mock private Clock mClock; @@ -95,7 +95,7 @@ public class WakeupControllerTest extends WifiBaseTest { when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); when(mWifiInjector.getWifiSettingsStore()).thenReturn(mWifiSettingsStore); - when(mWifiInjector.getWifiController()).thenReturn(mWifiController); + when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden); when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY)) .thenReturn(new int[]{DFS_CHANNEL_FREQ}); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java deleted file mode 100644 index 313e159c9..000000000 --- a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java +++ /dev/null @@ -1,1068 +0,0 @@ -/* - * Copyright (C) 2016 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 com.android.server.wifi.WifiController.CMD_AP_STOPPED; -import static com.android.server.wifi.WifiController.CMD_EMERGENCY_CALL_STATE_CHANGED; -import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED; -import static com.android.server.wifi.WifiController.CMD_RECOVERY_DISABLE_WIFI; -import static com.android.server.wifi.WifiController.CMD_RECOVERY_RESTART_WIFI; -import static com.android.server.wifi.WifiController.CMD_SCANNING_STOPPED; -import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED; -import static com.android.server.wifi.WifiController.CMD_SET_AP; -import static com.android.server.wifi.WifiController.CMD_STA_STOPPED; -import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.*; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.location.LocationManager; -import android.net.wifi.WifiManager; -import android.os.test.TestLooper; -import android.util.Log; - -import androidx.test.filters.SmallTest; - -import com.android.internal.R; -import com.android.internal.util.IState; -import com.android.internal.util.StateMachine; -import com.android.server.wifi.util.WifiPermissionsUtil; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.lang.reflect.Method; - -/** - * Test WifiController for changes in and out of ECM and SoftAP modes. - */ -@SmallTest -public class WifiControllerTest { - - private static final String TAG = "WifiControllerTest"; - - private static final int TEST_WIFI_RECOVERY_DELAY_MS = 2000; - - private void dumpState() { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - PrintWriter writer = new PrintWriter(stream); - mWifiController.dump(null, writer, null); - writer.flush(); - Log.d(TAG, "ClientModeImpl state -" + stream.toString()); - } - - private IState getCurrentState() throws Exception { - Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); - method.setAccessible(true); - return (IState) method.invoke(mWifiController); - } - - private void initializeSettingsStore() throws Exception { - when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); - } - - TestLooper mLooper; - @Mock Context mContext; - @Mock Resources mResources; - @Mock FrameworkFacade mFacade; - @Mock WifiSettingsStore mSettingsStore; - @Mock ClientModeImpl mClientModeImpl; - @Mock ActiveModeWarden mActiveModeWarden; - @Mock WifiPermissionsUtil mWifiPermissionsUtil; - - WifiController mWifiController; - - private BroadcastReceiver mBroadcastReceiver; - - private ClientModeManager.Listener mClientModeCallback; - private ScanOnlyModeManager.Listener mScanOnlyModeCallback; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mLooper = new TestLooper(); - - initializeSettingsStore(); - - when(mContext.getResources()).thenReturn(mResources); - - when(mResources.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay)) - .thenReturn(TEST_WIFI_RECOVERY_DELAY_MS); - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); - - mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(), - mSettingsStore, mFacade, mActiveModeWarden, mWifiPermissionsUtil); - mWifiController.start(); - mLooper.dispatchAll(); - - ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass( - BroadcastReceiver.class); - verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class)); - mBroadcastReceiver = bcastRxCaptor.getValue(); - - ArgumentCaptor<ClientModeManager.Listener> clientModeCallbackCaptor = - ArgumentCaptor.forClass(ClientModeManager.Listener.class); - verify(mActiveModeWarden).registerClientModeCallback(clientModeCallbackCaptor.capture()); - mClientModeCallback = clientModeCallbackCaptor.getValue(); - - ArgumentCaptor<ScanOnlyModeManager.Listener> scanOnlyModeCallbackCaptor = - ArgumentCaptor.forClass(ScanOnlyModeManager.Listener.class); - verify(mActiveModeWarden).registerScanOnlyCallback(scanOnlyModeCallbackCaptor.capture()); - mScanOnlyModeCallback = scanOnlyModeCallbackCaptor.getValue(); - - } - - @After - public void cleanUp() { - mLooper.dispatchAll(); - } - - /** - * Verify that toggling wifi from disabled starts client mode. - */ - @Test - public void enableWifi() throws Exception { - assertEquals("StaDisabledState", getCurrentState().getName()); - - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); - mWifiController.sendMessage(CMD_WIFI_TOGGLED); - mLooper.dispatchAll(); - assertEquals("StaEnabledState", getCurrentState().getName()); - } - - /** - * Test verifying that we can enter scan mode when the scan mode changes - */ - @Test - public void enableScanMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - } - - /** - * Verify that if scanning is enabled at startup, we enter scan mode - */ - @Test - public void testEnterScanModeAtStartWhenSet() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - - // reset to avoid the default behavior - reset(mActiveModeWarden); - - WifiController wifiController = new WifiController(mContext, mClientModeImpl, - mLooper.getLooper(), mSettingsStore, mFacade, mActiveModeWarden, - mWifiPermissionsUtil); - - wifiController.start(); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).disableWifi(); - verify(mActiveModeWarden).enterScanOnlyMode(); - } - - /** - * Do not enter scan mode if location mode disabled. - */ - @Test - public void testDoesNotEnterScanModeWhenLocationModeDisabled() throws Exception { - // Start a new WifiController with wifi disabled - when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); - - mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(), - mSettingsStore, mFacade, mActiveModeWarden, mWifiPermissionsUtil); - - reset(mActiveModeWarden); - mWifiController.start(); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).disableWifi(); - - // toggling scan always available is not sufficient for scan mode - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).enterScanOnlyMode(); - - } - - /** - * Only enter scan mode if location mode enabled - */ - @Test - public void testEnterScanModeWhenLocationModeEnabled() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); - - reset(mContext, mActiveModeWarden); - when(mContext.getResources()).thenReturn(mResources); - mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(), - mSettingsStore, mFacade, mActiveModeWarden, mWifiPermissionsUtil); - - mWifiController.start(); - mLooper.dispatchAll(); - - ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass( - BroadcastReceiver.class); - verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class)); - mBroadcastReceiver = bcastRxCaptor.getValue(); - - verify(mActiveModeWarden).disableWifi(); - - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); - Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); - - mBroadcastReceiver.onReceive(mContext, intent); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - } - - - - /** - * Disabling location mode when in scan mode will disable wifi - */ - @Test - public void testExitScanModeWhenLocationModeDisabled() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); - - reset(mContext, mActiveModeWarden); - when(mContext.getResources()).thenReturn(mResources); - mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(), - mSettingsStore, mFacade, mActiveModeWarden, mWifiPermissionsUtil); - mWifiController.start(); - mLooper.dispatchAll(); - - ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass( - BroadcastReceiver.class); - verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class)); - mBroadcastReceiver = bcastRxCaptor.getValue(); - - verify(mActiveModeWarden).enterScanOnlyMode(); - - when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); - Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); - - mBroadcastReceiver.onReceive(mContext, intent); - mLooper.dispatchAll(); - verify(mActiveModeWarden).disableWifi(); - } - - /** - * When in Client mode, make sure ECM triggers wifi shutdown. - */ - @Test - public void testEcmOnFromClientMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); - enableWifi(); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).shutdownWifi(); - } - - /** - * ECM disabling messages, when in client mode (not expected) do not trigger state changes. - */ - @Test - public void testEcmOffInClientMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); - enableWifi(); - - // Test with WifiDisableInECBM turned off - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).shutdownWifi(); - verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED); - } - - /** - * When ECM activates and we are in client mode, disabling ECM should return us to client mode. - */ - @Test - public void testEcmDisabledReturnsToClientMode() throws Exception { - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).shutdownWifi(); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).enterClientMode(); - } - - /** - * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed - * update. - */ - @Test - public void testEcmOnFromScanMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - verify(mActiveModeWarden).enterScanOnlyMode(); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).shutdownWifi(); - } - - /** - * When Ecm mode is disabled, we should not shut down scan mode if we get an emergency mode - * changed update, but we should turn off soft AP - */ - @Test - public void testEcmOffInScanMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - - // Test with WifiDisableInECBM turned off: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); - verify(mActiveModeWarden).enterScanOnlyMode(); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).shutdownWifi(); - verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED); - } - - /** - * When ECM is disabled, we should return to scan mode - */ - @Test - public void testEcmDisabledReturnsToScanMode() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).shutdownWifi(); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).enterScanOnlyMode(); - } - - /** - * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed - * update. - */ - @Test - public void testEcmOnFromSoftApMode() throws Exception { - mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget(); - mLooper.dispatchAll(); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - verify(mActiveModeWarden).enterSoftAPMode(any()); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).shutdownWifi(); - } - - /** - * When Ecm mode is disabled, we should shut down softap mode if we get an emergency mode - * changed update - */ - @Test - public void testEcmOffInSoftApMode() throws Exception { - mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget(); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterSoftAPMode(any()); - - // Test with WifiDisableInECBM turned off: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED); - } - - /** - * When ECM is activated and we were in softap mode, we should just return to wifi off when ECM - * ends - */ - @Test - public void testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget(); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterSoftAPMode(any()); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - reset(mActiveModeWarden); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - - verify(mActiveModeWarden).disableWifi(); - // no additional calls to enable softap - verify(mActiveModeWarden, never()).enterSoftAPMode(any()); - } - - /** - * Wifi should remain off when already disabled and we enter ECM. - */ - @Test - public void testEcmOnFromDisabledMode() throws Exception { - verify(mActiveModeWarden, never()).enterSoftAPMode(any()); - verify(mActiveModeWarden, never()).enterClientMode(); - verify(mActiveModeWarden, never()).enterScanOnlyMode(); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - } - - - /** - * Updates about call state change also trigger entry of ECM mode. - */ - @Test - public void testEnterEcmOnEmergencyCallStateChange() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test call state changed - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterClientMode(); - } - - /** - * Verify when both ECM and call state changes arrive, we enter ECM mode - */ - @Test - public void testEnterEcmWithBothSignals() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - // still only 1 shutdown - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - // stay in ecm, do not send an additional client mode trigger - verify(mActiveModeWarden, never()).enterClientMode(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - // now we can re-enable wifi - verify(mActiveModeWarden).enterClientMode(); - } - - /** - * Verify when both ECM and call state changes arrive but out of order, we enter ECM mode - */ - @Test - public void testEnterEcmWithBothSignalsOutOfOrder() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mLooper.dispatchAll(); - // still only 1 shutdown - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - // stay in ecm, do not send an additional client mode trigger - verify(mActiveModeWarden, never()).enterClientMode(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - // now we can re-enable wifi - verify(mActiveModeWarden).enterClientMode(); - } - - /** - * Verify when both ECM and call state changes arrive but completely out of order, - * we still enter and properly exit ECM mode - */ - @Test - public void testEnterEcmWithBothSignalsOppositeOrder() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - // still only 1 shutdown - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - // stay in ecm, do not send an additional client mode trigger - verify(mActiveModeWarden, never()).enterClientMode(); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - // now we can re-enable wifi - verify(mActiveModeWarden).enterClientMode(); - } - - - /** - * When ECM is active, we might get addition signals of ECM mode, we must not exit until they - * are all cleared. - */ - @Test - public void testProperExitFromEcmModeWithMultipleMessages() throws Exception { - verify(mActiveModeWarden).disableWifi(); - - enableWifi(); - verify(mActiveModeWarden).enterClientMode(); - - reset(mActiveModeWarden); - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0); - mLooper.dispatchAll(); - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - verify(mActiveModeWarden, never()).enterClientMode(); - - // now we will exit ECM - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0); - mLooper.dispatchAll(); - - // now we can re-enable wifi - verify(mActiveModeWarden).enterClientMode(); - } - - /** - * Toggling wifi when in ECM does not exit ecm mode and enable wifi - */ - @Test - public void testWifiDoesNotToggleOnWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - // now toggle wifi and verify we do not start wifi - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); - mWifiController.sendMessage(CMD_WIFI_TOGGLED); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).enterClientMode(); - } - - /** - * Toggling scan mode when in ECM does not exit ecm mode and enable scan mode - */ - @Test - public void testScanModeDoesNotToggleOnWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - // now enable scanning and verify we do not start wifi - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).enterScanOnlyMode(); - } - - /** - * Toggling softap mode when in ECM does not exit ecm mode and enable softap - */ - @Test - public void testSoftApModeDoesNotToggleOnWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - mWifiController.sendMessage(CMD_SET_AP); - mLooper.dispatchAll(); - - verify(mActiveModeWarden, never()).enterSoftAPMode(any()); - } - - /** - * Toggling off softap mode when in ECM does not induce a mode change - */ - @Test - public void testSoftApStoppedDoesNotSwitchModesWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_AP_STOPPED); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(mActiveModeWarden); - } - - /** - * Toggling softap mode when in airplane mode needs to enable softap - */ - @Test - public void testSoftApModeToggleWhenInAirplaneMode() throws Exception { - // Test with airplane mode turned on: - when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); - - // Turn on SoftAp. - mWifiController.sendMessage(CMD_SET_AP, 1); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterSoftAPMode(any()); - - // Turn off SoftAp. - mWifiController.sendMessage(CMD_SET_AP, 0, WifiManager.IFACE_IP_MODE_UNSPECIFIED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED); - } - - /** - * Toggling off scan mode when in ECM does not induce a mode change - */ - @Test - public void testScanModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_SCANNING_STOPPED); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(mActiveModeWarden); - } - - /** - * Toggling off client mode when in ECM does not induce a mode change - */ - @Test - public void testClientModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception { - - // Test with WifiDisableInECBM turned on: - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - // test ecm changed - mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verify(mActiveModeWarden).shutdownWifi(); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_STA_STOPPED); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(mActiveModeWarden); - } - - - /** - * When AP mode is enabled and wifi was previously in AP mode, we should return to - * StaEnabledState after the AP is disabled. - * Enter StaEnabledState, activate AP mode, disable AP mode. - * <p> - * Expected: AP should successfully start and exit, then return to StaEnabledState. - */ - @Test - public void testReturnToStaEnabledStateAfterAPModeShutdown() throws Exception { - enableWifi(); - assertEquals("StaEnabledState", getCurrentState().getName()); - - mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget(); - // add an "unexpected" sta mode stop to simulate a single interface device - mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED); - mLooper.dispatchAll(); - - when(mSettingsStore.getWifiSavedState()).thenReturn(1); - mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget(); - mLooper.dispatchAll(); - - InOrder inOrder = inOrder(mActiveModeWarden); - inOrder.verify(mActiveModeWarden).enterClientMode(); - assertEquals("StaEnabledState", getCurrentState().getName()); - } - - /** - * When AP mode is enabled and wifi is toggled on, we should transition to - * StaEnabledState after the AP is disabled. - * Enter StaEnabledState, activate AP mode, toggle WiFi. - * <p> - * Expected: AP should successfully start and exit, then return to StaEnabledState. - */ - @Test - public void testReturnToStaEnabledStateAfterWifiEnabledShutdown() throws Exception { - enableWifi(); - assertEquals("StaEnabledState", getCurrentState().getName()); - - mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget(); - mLooper.dispatchAll(); - - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); - mWifiController.obtainMessage(CMD_WIFI_TOGGLED).sendToTarget(); - mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget(); - mLooper.dispatchAll(); - - InOrder inOrder = inOrder(mActiveModeWarden); - inOrder.verify(mActiveModeWarden).enterClientMode(); - assertEquals("StaEnabledState", getCurrentState().getName()); - } - - @Test - public void testRestartWifiStackInStaEnabledStateTriggersBugReport() throws Exception { - enableWifi(); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI, - SelfRecovery.REASON_WIFINATIVE_FAILURE); - mLooper.dispatchAll(); - verify(mClientModeImpl).takeBugReport(anyString(), anyString()); - } - - @Test - public void testRestartWifiWatchdogDoesNotTriggerBugReport() throws Exception { - enableWifi(); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI, - SelfRecovery.REASON_LAST_RESORT_WATCHDOG); - mLooper.dispatchAll(); - verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString()); - } - - /** - * When in sta mode, CMD_RECOVERY_DISABLE_WIFI messages should trigger wifi to disable. - */ - @Test - public void testRecoveryDisabledTurnsWifiOff() throws Exception { - enableWifi(); - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_RECOVERY_DISABLE_WIFI); - mLooper.dispatchAll(); - verify(mActiveModeWarden).disableWifi(); - } - - /** - * When wifi is disabled, CMD_RECOVERY_DISABLE_WIFI should not trigger a state change. - */ - @Test - public void testRecoveryDisabledWhenWifiAlreadyOff() throws Exception { - assertEquals("StaDisabledState", getCurrentState().getName()); - mWifiController.sendMessage(CMD_RECOVERY_DISABLE_WIFI); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - } - - /** - * The command to trigger a WiFi reset should not trigger any action by WifiController if we - * are not in STA mode. - * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures - * should be ignored. - * Create and start WifiController in StaDisabledState, send command to restart WiFi - * <p> - * Expected: WiFiController should not call ActiveModeWarden.disableWifi() - */ - @Test - public void testRestartWifiStackInStaDisabledState() throws Exception { - // Start a new WifiController with wifi disabled - when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); - when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); - - mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(), - mSettingsStore, mFacade, mActiveModeWarden, mWifiPermissionsUtil); - - mWifiController.start(); - mLooper.dispatchAll(); - - reset(mClientModeImpl); - assertEquals("StaDisabledState", getCurrentState().getName()); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI); - mLooper.dispatchAll(); - verify(mActiveModeWarden).disableWifi(); - } - - /** - * The command to trigger a WiFi reset should not trigger any action by WifiController if we - * are not in STA mode, even if scans are allowed. - * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures - * should be ignored. - * Create and start WifiController in StaDisabledState, send command to restart WiFi - * <p> - * Expected: WiFiController should not call ActiveModeWarden.disableWifi() or - * ActiveModeWarden.shutdownWifi(). - */ - @Test - public void testRestartWifiStackInStaDisabledWithScanState() throws Exception { - when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); - mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterScanOnlyMode(); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI); - mLooper.dispatchAll(); - mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); - mLooper.dispatchAll(); - InOrder inOrder = inOrder(mActiveModeWarden); - inOrder.verify(mActiveModeWarden).disableWifi(); - inOrder.verify(mActiveModeWarden).enterScanOnlyMode(); - } - - /** - * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through - * the ActiveModeWarden.shutdownWifi() call when in STA mode. - * WiFi is in connect mode, calls to reset the wifi stack due to connection failures - * should trigger a supplicant stop, and subsequently, a driver reload. - * Create and start WifiController in StaEnabledState, send command to restart WiFi - * <p> - * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and - * ActiveModeWarden should enter CONNECT_MODE and the wifi driver should be started. - */ - @Test - public void testRestartWifiStackInStaEnabledState() throws Exception { - enableWifi(); - assertEquals("StaEnabledState", getCurrentState().getName()); - - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI); - mLooper.dispatchAll(); - mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); - mLooper.dispatchAll(); - - InOrder inOrder = inOrder(mActiveModeWarden); - inOrder.verify(mActiveModeWarden).shutdownWifi(); - inOrder.verify(mActiveModeWarden).enterClientMode(); - assertEquals("StaEnabledState", getCurrentState().getName()); - } - - /** - * The command to trigger a WiFi reset should not trigger a reset when in ECM mode. - * Enable wifi and enter ECM state, send command to restart wifi. - * <p> - * Expected: The command to trigger a wifi reset should be ignored and we should remain in ECM - * mode. - */ - @Test - public void testRestartWifiStackDoesNotExitECMMode() throws Exception { - enableWifi(); - assertEquals("StaEnabledState", getCurrentState().getName()); - when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); - - mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - verify(mActiveModeWarden).shutdownWifi(); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI); - mLooper.dispatchAll(); - assertEquals("EcmState", getCurrentState().getName()); - - verifyZeroInteractions(mActiveModeWarden); - } - - /** - * The command to trigger a WiFi reset should trigger a reset when in AP mode. - * Enter AP mode, send command to restart wifi. - * <p> - * Expected: The command to trigger a wifi reset should trigger wifi shutdown. - */ - @Test - public void testRestartWifiStackFullyStopsWifi() throws Exception { - mWifiController.obtainMessage(CMD_SET_AP, 1).sendToTarget(); - mLooper.dispatchAll(); - verify(mActiveModeWarden).enterSoftAPMode(any()); - - reset(mActiveModeWarden); - mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI); - mLooper.dispatchAll(); - verify(mActiveModeWarden).shutdownWifi(); - } -} diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java index 75b21df7c..023fddb17 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java @@ -75,12 +75,13 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest { when(mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(true); when(mDeviceConfigFacade.getAbnormalConnectionDurationMs()).thenReturn( DEFAULT_ABNORMAL_CONNECTION_DURATION_MS); + WifiThreadRunner wifiThreadRunner = new WifiThreadRunner(new Handler(mLooper.getLooper())); mLastResortWatchdog = new WifiLastResortWatchdog(mWifiInjector, mContext, mClock, - mWifiMetrics, mClientModeImpl, mLooper.getLooper(), mDeviceConfigFacade); + mWifiMetrics, mClientModeImpl, mLooper.getLooper(), mDeviceConfigFacade, + wifiThreadRunner); mLastResortWatchdog.setBugReportProbability(1); when(mClientModeImpl.getWifiInfo()).thenReturn(mWifiInfo); when(mWifiInfo.getSSID()).thenReturn(TEST_NETWORK_SSID); - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mLastResortWatchdog.getHandler()); } private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids, diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 137f881d0..e0140cf07 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -37,8 +37,6 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G; import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR; -import static com.android.server.wifi.WifiController.CMD_SET_AP; -import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -219,7 +217,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Mock WifiInjector mWifiInjector; @Mock WifiCountryCode mWifiCountryCode; @Mock Clock mClock; - @Mock WifiController mWifiController; @Mock WifiTrafficPoller mWifiTrafficPoller; @Mock ClientModeImpl mClientModeImpl; @Mock ActiveModeWarden mActiveModeWarden; @@ -262,6 +259,7 @@ public class WifiServiceImplTest extends WifiBaseTest { @Mock WifiScoreCard mWifiScoreCard; @Mock PasspointManager mPasspointManager; @Mock IDppCallback mDppCallback; + @Mock SarManager mSarManager; @Spy FakeWifiLog mLog; @@ -340,7 +338,6 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mRequestInfo2.getPid()).thenReturn(mPid2); when(mWifiInjector.getUserManager()).thenReturn(mUserManager); when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode); - when(mWifiInjector.getWifiController()).thenReturn(mWifiController); when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl); when(mClientModeImpl.syncInitialize(any())).thenReturn(true); @@ -386,6 +383,8 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager); when(mClientModeImpl.getWifiScoreReport()).thenReturn(mWifiScoreReport); when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard); + when(mWifiInjector.getSarManager()).thenReturn(mSarManager); + when(mWifiInjector.getWifiThreadRunner()).thenReturn(new WifiThreadRunner(mHandler)); when(mClientModeImpl.syncStartSubscriptionProvisioning(anyInt(), any(OsuProvider.class), any(IProvisioningCallback.class), any())).thenReturn(true); // Create an OSU provider that can be provisioned via an open OSU AP @@ -403,17 +402,7 @@ public class WifiServiceImplTest extends WifiBaseTest { anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED); when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true); - ArgumentCaptor<SoftApCallback> softApCallbackCaptor = - ArgumentCaptor.forClass(SoftApCallback.class); - mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); - verify(mActiveModeWarden).registerSoftApCallback(softApCallbackCaptor.capture()); - mStateMachineSoftApCallback = softApCallbackCaptor.getValue(); - ArgumentCaptor<SoftApCallback> lohsCallbackCaptor = - ArgumentCaptor.forClass(SoftApCallback.class); - mLohsInterfaceName = WIFI_IFACE_NAME; - verify(mActiveModeWarden).registerLohsCallback(lohsCallbackCaptor.capture()); - mLohsCallback = lohsCallbackCaptor.getValue(); - mWifiServiceImpl.setWifiHandlerLogForTest(mLog); + mWifiServiceImpl = makeWifiServiceImpl(); mDppCallback = new IDppCallback() { @Override public void onSuccessConfigReceived(int newNetworkId) throws RemoteException { @@ -442,6 +431,23 @@ public class WifiServiceImplTest extends WifiBaseTest { }; } + private WifiServiceImpl makeWifiServiceImpl() { + reset(mActiveModeWarden); + WifiServiceImpl wifiServiceImpl = + new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); + wifiServiceImpl.setWifiHandlerLogForTest(mLog); + ArgumentCaptor<SoftApCallback> softApCallbackCaptor = + ArgumentCaptor.forClass(SoftApCallback.class); + verify(mActiveModeWarden).registerSoftApCallback(softApCallbackCaptor.capture()); + mStateMachineSoftApCallback = softApCallbackCaptor.getValue(); + ArgumentCaptor<SoftApCallback> lohsCallbackCaptor = + ArgumentCaptor.forClass(SoftApCallback.class); + mLohsInterfaceName = WIFI_IFACE_NAME; + verify(mActiveModeWarden).registerLohsCallback(lohsCallbackCaptor.capture()); + mLohsCallback = lohsCallbackCaptor.getValue(); + return wifiServiceImpl; + } + private WifiAsyncChannelTester verifyAsyncChannelHalfConnected() throws RemoteException { WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector); Handler handler = mock(Handler.class); @@ -493,7 +499,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testDumpNullArgs() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); } @@ -514,7 +520,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testWifiScoreReportDump() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); @@ -590,7 +596,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -604,7 +610,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -624,7 +630,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -642,7 +648,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -659,7 +665,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -676,7 +682,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -695,7 +701,7 @@ public class WifiServiceImplTest extends WifiBaseTest { } catch (SecurityException e) { } - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -711,7 +717,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -727,7 +733,7 @@ public class WifiServiceImplTest extends WifiBaseTest { .thenReturn(PackageManager.PERMISSION_GRANTED); assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -747,7 +753,7 @@ public class WifiServiceImplTest extends WifiBaseTest { .thenReturn(PackageManager.PERMISSION_DENIED); assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -786,7 +792,7 @@ public class WifiServiceImplTest extends WifiBaseTest { .thenReturn(PackageManager.PERMISSION_GRANTED); when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -810,7 +816,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); verify(mSettingsStore, never()).handleWifiToggled(anyBoolean()); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } @@ -823,7 +829,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -851,7 +857,7 @@ public class WifiServiceImplTest extends WifiBaseTest { anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -864,7 +870,7 @@ public class WifiServiceImplTest extends WifiBaseTest { anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -884,7 +890,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -902,7 +908,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } @@ -920,7 +926,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -937,7 +943,7 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -949,7 +955,7 @@ public class WifiServiceImplTest extends WifiBaseTest { anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false); assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); - verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -1033,7 +1039,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetWifiApConfigurationSuccess() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); mWifiServiceImpl.setWifiHandlerLogForTest(mLog); @@ -1052,7 +1058,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetWifiApEnabled() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); // ap should be disabled when wifi hasn't been started assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState()); @@ -1067,8 +1073,7 @@ public class WifiServiceImplTest extends WifiBaseTest { // send an ap state change to verify WifiServiceImpl is updated verifyApRegistration(); mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); - mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, - SAP_START_FAILURE_GENERAL); + mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); mLooper.dispatchAll(); assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState()); @@ -1097,8 +1102,8 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testWifiControllerStartsWhenDeviceBootsWithWifiDisabled() { when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); - verify(mWifiController).start(); - verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED); + verify(mActiveModeWarden).start(); + verify(mActiveModeWarden, never()).wifiToggled(); } /** @@ -1113,8 +1118,8 @@ public class WifiServiceImplTest extends WifiBaseTest { when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); mWifiServiceImpl.checkAndStartWifi(); - verify(mWifiController).start(); - verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED); + verify(mActiveModeWarden).start(); + verify(mActiveModeWarden).wifiToggled(); } /** @@ -1124,8 +1129,7 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testStartSoftApWithPermissionsAndNullConfig() { boolean result = mWifiServiceImpl.startSoftAp(null); assertTrue(result); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture()); + verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture()); assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); } @@ -1136,7 +1140,7 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testStartSoftApWithPermissionsAndInvalidConfig() { boolean result = mWifiServiceImpl.startSoftAp(mApConfig); assertFalse(result); - verifyZeroInteractions(mWifiController); + verifyZeroInteractions(mActiveModeWarden); } /** @@ -1147,8 +1151,7 @@ public class WifiServiceImplTest extends WifiBaseTest { WifiConfiguration config = createValidSoftApConfiguration(); boolean result = mWifiServiceImpl.startSoftAp(config); assertTrue(result); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture()); + verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture()); assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); } @@ -1171,8 +1174,7 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testStopSoftApWithPermissions() { boolean result = mWifiServiceImpl.stopSoftAp(); assertTrue(result); - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_TETHERED)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED); } /** @@ -1192,7 +1194,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testStartScanFailureAppOpsIgnored() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager) .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME); assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); @@ -1204,7 +1206,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testStartScanFailureInCanAccessScanResultsPermission() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); doThrow(new SecurityException()).when(mWifiPermissionsUtil) .enforceCanAccessScanResults(SCAN_PACKAGE_NAME, Process.myUid()); assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); @@ -1216,7 +1218,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testStartScanFailureInRunWithScissors() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); doReturn(false).when(mHandlerSpyForCmiRunWithScissors) .runWithScissors(any(), anyLong()); assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); @@ -1228,7 +1230,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testStartScanFailureFromScanRequestProxy() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false); assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME); @@ -1421,7 +1423,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetScanResults() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); ScanResult[] scanResults = ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0] @@ -1443,7 +1445,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetScanResultsFailureInRunWithScissors() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); doReturn(false).when(mHandlerSpyForCmiRunWithScissors) .runWithScissors(any(), anyLong()); @@ -1534,23 +1536,20 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testTetheringDoesNotStartWhenAlreadyTetheringActive() throws Exception { - setupClientModeImplHandlerForPost(); - WifiConfiguration config = createValidSoftApConfiguration(); assertTrue(mWifiServiceImpl.startSoftAp(config)); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); + verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture()); assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState()); - reset(mWifiController); + reset(mActiveModeWarden); // Start another session without a stop, that should fail. assertFalse(mWifiServiceImpl.startSoftAp(createValidSoftApConfiguration())); - verifyNoMoreInteractions(mWifiController); + verifyNoMoreInteractions(mActiveModeWarden); } /** @@ -1558,8 +1557,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception { - setupClientModeImplHandlerForPost(); - WifiConfiguration config = createValidSoftApConfiguration(); assertTrue(mWifiServiceImpl.startSoftAp(config)); mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); @@ -1608,7 +1605,7 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.stopLocalOnlyHotspot(); mLooper.dispatchAll(); // there is nothing registered, so this shouldn't do anything - verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); + verify(mActiveModeWarden, never()).stopSoftAp(anyInt()); } /** @@ -1626,7 +1623,7 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.stopLocalOnlyHotspot(); mLooper.dispatchAll(); // there is still a valid registered request - do not tear down LOHS - verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); + verify(mActiveModeWarden, never()).stopSoftAp(anyInt()); } /** @@ -1637,8 +1634,7 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testStopLocalOnlyHotspotTriggersStopWithOneRegisteredRequest() throws Exception { setupLocalOnlyHotspot(); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class)); + verify(mActiveModeWarden).startSoftAp(any()); mWifiServiceImpl.stopLocalOnlyHotspot(); mLooper.dispatchAll(); @@ -1648,8 +1644,7 @@ public class WifiServiceImplTest extends WifiBaseTest { eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString()); // there is was only one request registered, we should tear down LOHS - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } /** @@ -1683,8 +1678,7 @@ public class WifiServiceImplTest extends WifiBaseTest { } private void verifyLohsBand(int expectedBand) { - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture()); + verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture()); final WifiConfiguration configuration = mSoftApModeConfigCaptor.getValue().mConfig; assertNotNull(configuration); assertEquals(expectedBand, configuration.apBand); @@ -1700,8 +1694,7 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.new LocalOnlyRequestorCallback(); binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); - verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden, never()).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } /** @@ -1722,16 +1715,15 @@ public class WifiServiceImplTest extends WifiBaseTest { setupLocalOnlyHotspot(); binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); - verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); + verify(mActiveModeWarden, never()).stopSoftAp(anyInt()); - reset(mWifiController); + reset(mActiveModeWarden); // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder // death requestor was removed mWifiServiceImpl.stopLocalOnlyHotspot(); mLooper.dispatchAll(); - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } /** @@ -1789,8 +1781,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void registerSoftApCallbackFailureOnLinkToDeath() throws Exception { - setupClientModeImplHandlerForPost(); - doThrow(new RemoteException()) .when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1); @@ -1826,8 +1816,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void replacesOldCallbackWithNewCallbackWhenRegisteringTwice() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mAppBinder, mClientSoftApCallback, callbackIdentifier); registerSoftApCallbackAndVerify( @@ -1851,8 +1839,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void unregisterSoftApCallbackRemovesCallback() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); @@ -1871,8 +1857,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); @@ -1891,8 +1875,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, callbackIdentifier); @@ -1928,8 +1910,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); @@ -1940,8 +1920,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void unregistersSoftApCallbackOnBinderDied() throws Exception { - setupClientModeImplHandlerForPost(); - ArgumentCaptor<IBinder.DeathRecipient> drCaptor = ArgumentCaptor.forClass(IBinder.DeathRecipient.class); final int callbackIdentifier = 1; @@ -1964,8 +1942,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); @@ -1980,8 +1956,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception { - setupClientModeImplHandlerForPost(); - final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); @@ -1996,8 +1970,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception { - setupClientModeImplHandlerForPost(); - final int testNumClients = 4; mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); @@ -2064,7 +2036,6 @@ public class WifiServiceImplTest extends WifiBaseTest { * Common setup for starting a LOHS. */ private void setupLocalOnlyHotspot() throws Exception { - setupClientModeImplHandlerForPost(); when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); @@ -2203,7 +2174,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception { - setupClientModeImplHandlerForPost(); when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); @@ -2238,7 +2208,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception { - setupClientModeImplHandlerForPost(); when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); @@ -2262,13 +2231,10 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); mLooper.dispatchAll(); - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } /** @@ -2278,8 +2244,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady() throws Exception { - setupClientModeImplHandlerForPost(); - registerLOHSRequestFull(); mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); @@ -2302,8 +2266,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR); @@ -2327,7 +2289,7 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception { setupLocalOnlyHotspot(); - reset(mWifiController); + reset(mActiveModeWarden); mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); mLooper.dispatchAll(); @@ -2337,8 +2299,7 @@ public class WifiServiceImplTest extends WifiBaseTest { assertEquals(HOTSPOT_FAILED, message.what); assertEquals(ERROR_GENERIC, message.arg1); - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); reset(mHandler); @@ -2355,14 +2316,11 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testStopSoftApWhenIpConfigFails() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); mLooper.dispatchAll(); - verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), - eq(IFACE_IP_MODE_TETHERED)); + verify(mActiveModeWarden).stopSoftAp(IFACE_IP_MODE_TETHERED); } /** @@ -2371,8 +2329,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception { - setupClientModeImplHandlerForPost(); - registerLOHSRequestFull(); mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); @@ -2417,7 +2373,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback() throws Exception { - setupClientModeImplHandlerForPost(); when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); verifyApRegistration(); @@ -2974,18 +2929,15 @@ public class WifiServiceImplTest extends WifiBaseTest { verify(mWifiCountryCode, never()).setCountryCode(TEST_COUNTRY_CODE); } - private void setupClientModeImplHandlerForPost() { - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler); - } - /** - * Set the wifi state machine mock to return a handler created on test thread. + * Set the WifiInjector mock to return a WifiThreadRunner created on test thread. */ - private void setupClientModeImplHandlerForRunWithScissors() { + private void setupWifiThreadRunnerForSync() { HandlerThread handlerThread = createAndStartHandlerThreadForRunWithScissors(); mHandlerSpyForCmiRunWithScissors = spy(handlerThread.getThreadHandler()); - when(mWifiInjector.getClientModeImplHandler()) - .thenReturn(mHandlerSpyForCmiRunWithScissors); + when(mWifiInjector.getWifiThreadRunner()) + .thenReturn(new WifiThreadRunner(mHandlerSpyForCmiRunWithScissors)); + mWifiServiceImpl = makeWifiServiceImpl(); } private HandlerThread createAndStartHandlerThreadForRunWithScissors() { @@ -3000,7 +2952,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testHandleDelayedScanAfterIdleMode() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); mWifiServiceImpl.checkAndStartWifi(); verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), @@ -3079,7 +3031,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testPackageRemovedBroadcastHandling() { - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler); mWifiServiceImpl.checkAndStartWifi(); verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), argThat((IntentFilter filter) -> @@ -3104,7 +3055,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testPackageRemovedBroadcastHandlingWithNoUid() { - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler); mWifiServiceImpl.checkAndStartWifi(); verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), argThat((IntentFilter filter) -> @@ -3128,7 +3078,6 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testPackageRemovedBroadcastHandlingWithNoPackageName() { - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler); mWifiServiceImpl.checkAndStartWifi(); verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), argThat((IntentFilter filter) -> @@ -3361,8 +3310,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void registerTrafficStateCallbackAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.registerTrafficStateCallback( mAppBinder, mTrafficStateCallback, TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER); mLooper.dispatchAll(); @@ -3375,8 +3322,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void unregisterTrafficStateCallbackAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.unregisterTrafficStateCallback(0); mLooper.dispatchAll(); verify(mWifiTrafficPoller).removeCallback(0); @@ -3438,8 +3383,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void registerNetworkRequestMatchCallbackAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.registerNetworkRequestMatchCallback( mAppBinder, mNetworkRequestMatchCallback, TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); @@ -3455,8 +3398,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void unregisterNetworkRequestMatchCallbackAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.unregisterNetworkRequestMatchCallback( TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); mLooper.dispatchAll(); @@ -3469,8 +3410,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testFactoryReset() throws Exception { - setupClientModeImplHandlerForPost(); - when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); @@ -3718,7 +3657,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testAddNetworkSuggestions() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString())) .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); @@ -3745,7 +3684,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testRemoveNetworkSuggestions() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString())) .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID); @@ -3772,7 +3711,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetNetworkSuggestions() { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); List<WifiNetworkSuggestion> testList = new ArrayList<>(); when(mWifiNetworkSuggestionsManager.get(anyString())).thenReturn(testList); assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME)); @@ -3813,7 +3752,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetFactoryMacAddresses() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); final String[] factoryMacs = mWifiServiceImpl.getFactoryMacAddresses(); @@ -3828,7 +3767,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetFactoryMacAddressesPostFail() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); doReturn(false).when(mHandlerSpyForCmiRunWithScissors) .runWithScissors(any(), anyLong()); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); @@ -3841,7 +3780,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetFactoryMacAddressesFail() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mClientModeImpl.getFactoryMacAddress()).thenReturn(null); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); assertNull(mWifiServiceImpl.getFactoryMacAddresses()); @@ -3854,7 +3793,7 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testGetFactoryMacAddressesFailNoNetworkSettingsPermission() throws Exception { - setupClientModeImplHandlerForRunWithScissors(); + setupWifiThreadRunnerForSync(); when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); try { @@ -3888,8 +3827,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void setDeviceMobilityStateRunsOnHandler() { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY); verify(mClientModeImpl, never()).setDeviceMobilityState(anyInt()); mLooper.dispatchAll(); @@ -3951,8 +3888,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testAddOnWifiUsabilityStatsListenerAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.addOnWifiUsabilityStatsListener(mAppBinder, mOnWifiUsabilityStatsListener, TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER); mLooper.dispatchAll(); @@ -3966,8 +3901,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testRemoveOnWifiUsabilityStatsListenerAndVerify() throws Exception { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.removeOnWifiUsabilityStatsListener(0); mLooper.dispatchAll(); verify(mWifiMetrics).removeOnWifiUsabilityListener(0); @@ -3996,8 +3929,6 @@ public class WifiServiceImplTest extends WifiBaseTest { */ @Test public void testWifiUsabilityScoreUpdateAfterScoreEvent() { - setupClientModeImplHandlerForPost(); - mWifiServiceImpl.updateWifiUsabilityScore(anyInt(), anyInt(), 15); mLooper.dispatchAll(); verify(mClientModeImpl).updateWifiUsabilityScore(anyInt(), anyInt(), anyInt()); @@ -4016,13 +3947,12 @@ public class WifiServiceImplTest extends WifiBaseTest { mLohsInterfaceName = WIFI_IFACE_NAME2; setupLocalOnlyHotspot(); - reset(mWifiController); + reset(mActiveModeWarden); // start tethering boolean tetheringResult = mWifiServiceImpl.startSoftAp(null); assertTrue(tetheringResult); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class)); + verify(mActiveModeWarden).startSoftAp(any()); mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); } @@ -4038,8 +3968,7 @@ public class WifiServiceImplTest extends WifiBaseTest { // verify LOHS got stopped verify(mHandler).handleMessage(mMessageCaptor.capture()); assertEquals(HOTSPOT_FAILED, mMessageCaptor.getValue().what); - verify(mWifiController) - .sendMessage(eq(CMD_SET_AP), eq(0), eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)); + verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } /** @@ -4052,7 +3981,7 @@ public class WifiServiceImplTest extends WifiBaseTest { // verify LOHS didn't get stopped verify(mHandler, never()).handleMessage(any(Message.class)); - verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), anyInt()); + verify(mActiveModeWarden, never()).stopSoftAp(anyInt()); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java new file mode 100644 index 000000000..cd3aff397 --- /dev/null +++ b/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.os.Handler; +import android.os.HandlerThread; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import java.util.function.Supplier; + +@SmallTest +public class WifiThreadRunnerTest { + + private static final int RESULT = 2; + + private WifiThreadRunner mWifiThreadRunner; + + @Mock private Runnable mRunnable; + + private Handler mHandler; + + @Spy private Supplier<Integer> mSupplier = () -> RESULT; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + HandlerThread mHandlerThread = new HandlerThread("WifiThreadRunnerTestHandlerThread"); + mHandlerThread.start(); + + // runWithScissors() is a final method that cannot be mocked, instead wrap it in a spy, + // then it can be mocked + mHandler = spy(mHandlerThread.getThreadHandler()); + + mWifiThreadRunner = new WifiThreadRunner(mHandler); + } + + @Test + public void callSuccess_returnExpectedValue() { + // doAnswer(<lambda>).when(<spy>).method(<args>) syntax is needed for spies instead of + // when(<mock>.method(<args>)).thenAnswer(<lambda>) for mocks + doAnswer(invocation -> { + Object[] args = invocation.getArguments(); + Runnable runnable = (Runnable) args[0]; + runnable.run(); + return true; + }).when(mHandler).runWithScissors(any(), anyLong()); + + Integer result = mWifiThreadRunner.call(mSupplier); + + assertThat(result).isEqualTo(RESULT); + verify(mSupplier).get(); + } + + @Test + public void callFailure_returnNull() { + doReturn(false).when(mHandler).runWithScissors(any(), anyLong()); + + Integer result = mWifiThreadRunner.call(mSupplier); + + assertThat(result).isNull(); + verify(mSupplier, never()).get(); + } + + @Test + public void runSuccess() { + doAnswer(invocation -> { + Object[] args = invocation.getArguments(); + Runnable runnable = (Runnable) args[0]; + runnable.run(); + return true; + }).when(mHandler).runWithScissors(any(), anyLong()); + + boolean result = mWifiThreadRunner.run(mRunnable); + + assertThat(result).isTrue(); + verify(mRunnable).run(); + } + + @Test + public void runFailure() { + doReturn(false).when(mHandler).runWithScissors(any(), anyLong()); + + boolean runSuccess = mWifiThreadRunner.run(mRunnable); + + assertThat(runSuccess).isFalse(); + verify(mRunnable, never()).run(); + } + + @Test + public void postSuccess() { + doReturn(true).when(mHandler).post(any()); + + boolean postSuccess = mWifiThreadRunner.post(mRunnable); + + assertThat(postSuccess).isTrue(); + verify(mHandler).post(mRunnable); + // assert that the runnable is not run on the calling thread + verify(mRunnable, never()).run(); + } + + @Test + public void postFailure() { + doReturn(false).when(mHandler).post(any()); + + boolean postSuccess = mWifiThreadRunner.post(mRunnable); + + assertThat(postSuccess).isFalse(); + verify(mHandler).post(mRunnable); + verify(mRunnable, never()).run(); + } +} |