1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; 20 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 21 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; 22 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; 23 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; 24 25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 26 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY; 27 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY; 28 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY; 29 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED; 30 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT; 31 import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_LOCAL_ONLY; 32 import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_TETHERED; 33 import static com.android.server.wifi.ActiveModeWarden.INTERNAL_REQUESTOR_WS; 34 import static com.android.server.wifi.TestUtil.addCapabilitiesToBitset; 35 import static com.android.server.wifi.TestUtil.combineBitsets; 36 import static com.android.server.wifi.TestUtil.createCapabilityBitset; 37 import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_STA_BANDS; 38 39 import static com.google.common.truth.Truth.assertThat; 40 import static com.google.common.truth.Truth.assertWithMessage; 41 42 import static org.junit.Assert.assertEquals; 43 import static org.junit.Assert.assertFalse; 44 import static org.junit.Assert.assertNull; 45 import static org.junit.Assert.assertTrue; 46 import static org.junit.Assert.fail; 47 import static org.junit.Assume.assumeTrue; 48 import static org.mockito.ArgumentMatchers.anyBoolean; 49 import static org.mockito.ArgumentMatchers.argThat; 50 import static org.mockito.Mockito.any; 51 import static org.mockito.Mockito.anyInt; 52 import static org.mockito.Mockito.anyString; 53 import static org.mockito.Mockito.atLeastOnce; 54 import static org.mockito.Mockito.clearInvocations; 55 import static org.mockito.Mockito.doAnswer; 56 import static org.mockito.Mockito.doThrow; 57 import static org.mockito.Mockito.eq; 58 import static org.mockito.Mockito.inOrder; 59 import static org.mockito.Mockito.isNull; 60 import static org.mockito.Mockito.mock; 61 import static org.mockito.Mockito.mockingDetails; 62 import static org.mockito.Mockito.never; 63 import static org.mockito.Mockito.reset; 64 import static org.mockito.Mockito.times; 65 import static org.mockito.Mockito.verify; 66 import static org.mockito.Mockito.verifyNoMoreInteractions; 67 import static org.mockito.Mockito.verifyZeroInteractions; 68 import static org.mockito.Mockito.when; 69 70 import android.annotation.Nullable; 71 import android.content.BroadcastReceiver; 72 import android.content.Intent; 73 import android.content.pm.PackageManager; 74 import android.location.LocationManager; 75 import android.net.MacAddress; 76 import android.net.Network; 77 import android.net.wifi.ISubsystemRestartCallback; 78 import android.net.wifi.IWifiConnectedNetworkScorer; 79 import android.net.wifi.IWifiNetworkStateChangedListener; 80 import android.net.wifi.IWifiStateChangedListener; 81 import android.net.wifi.SoftApCapability; 82 import android.net.wifi.SoftApConfiguration; 83 import android.net.wifi.SoftApConfiguration.Builder; 84 import android.net.wifi.SoftApInfo; 85 import android.net.wifi.SoftApState; 86 import android.net.wifi.WifiClient; 87 import android.net.wifi.WifiConfiguration; 88 import android.net.wifi.WifiContext; 89 import android.net.wifi.WifiManager; 90 import android.net.wifi.WifiScanner; 91 import android.net.wifi.util.WifiResourceCache; 92 import android.os.BatteryStatsManager; 93 import android.os.Build; 94 import android.os.Handler; 95 import android.os.IBinder; 96 import android.os.Process; 97 import android.os.RemoteException; 98 import android.os.UserManager; 99 import android.os.WorkSource; 100 import android.os.test.TestLooper; 101 import android.telephony.TelephonyManager; 102 import android.util.LocalLog; 103 import android.util.Log; 104 105 import androidx.test.filters.SmallTest; 106 107 import com.android.dx.mockito.inline.extended.StaticMockitoSession; 108 import com.android.modules.utils.build.SdkLevel; 109 import com.android.server.wifi.ActiveModeManager.ClientConnectivityRole; 110 import com.android.server.wifi.ActiveModeManager.Listener; 111 import com.android.server.wifi.ActiveModeManager.SoftApRole; 112 import com.android.server.wifi.ActiveModeWarden.ExternalClientModeManagerRequestListener; 113 import com.android.server.wifi.util.GeneralUtil.Mutable; 114 import com.android.server.wifi.util.LastCallerInfoManager; 115 import com.android.server.wifi.util.WifiPermissionsUtil; 116 import com.android.wifi.resources.R; 117 118 import org.junit.After; 119 import org.junit.Before; 120 import org.junit.Test; 121 import org.mockito.ArgumentCaptor; 122 import org.mockito.InOrder; 123 import org.mockito.Mock; 124 import org.mockito.Mockito; 125 import org.mockito.MockitoAnnotations; 126 import org.mockito.invocation.InvocationOnMock; 127 import org.mockito.stubbing.Answer; 128 129 import java.io.ByteArrayOutputStream; 130 import java.io.PrintWriter; 131 import java.util.ArrayList; 132 import java.util.BitSet; 133 import java.util.Collection; 134 import java.util.HashMap; 135 import java.util.List; 136 import java.util.Map; 137 import java.util.Set; 138 import java.util.stream.Collectors; 139 140 /** 141 * Unit tests for {@link com.android.server.wifi.ActiveModeWarden}. 142 */ 143 @SmallTest 144 public class ActiveModeWardenTest extends WifiBaseTest { 145 public static final String TAG = "WifiActiveModeWardenTest"; 146 147 private static final String ENABLED_STATE_STRING = "EnabledState"; 148 private static final String DISABLED_STATE_STRING = "DisabledState"; 149 private static final String TEST_SSID_1 = "\"Ssid12345\""; 150 private static final String TEST_SSID_2 = "\"Ssid45678\""; 151 private static final String TEST_SSID_3 = "\"Ssid98765\""; 152 private static final String TEST_BSSID_1 = "01:12:23:34:45:56"; 153 private static final String TEST_BSSID_2 = "10:21:32:43:54:65"; 154 private static final String TEST_BSSID_3 = "11:22:33:44:55:66"; 155 156 private static final String WIFI_IFACE_NAME = "mockWlan"; 157 private static final String WIFI_IFACE_NAME_1 = "mockWlan1"; 158 private static final int TEST_WIFI_RECOVERY_DELAY_MS = 2000; 159 private static final int TEST_AP_FREQUENCY = 2412; 160 private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ; 161 private static final int TEST_UID = 435546654; 162 private static final BitSet TEST_FEATURE_SET = createCapabilityBitset( 163 WifiManager.WIFI_FEATURE_P2P, WifiManager.WIFI_FEATURE_PNO, 164 WifiManager.WIFI_FEATURE_OWE, WifiManager.WIFI_FEATURE_DPP); 165 private static final String TEST_PACKAGE = "com.test"; 166 private static final String TEST_COUNTRYCODE = "US"; 167 private static final WorkSource TEST_WORKSOURCE = new WorkSource(TEST_UID, TEST_PACKAGE); 168 private static final WorkSource SETTINGS_WORKSOURCE = 169 new WorkSource(Process.SYSTEM_UID, "system-service"); 170 private static final int TEST_SUPPORTED_BANDS = 15; 171 172 TestLooper mLooper; 173 @Mock WifiInjector mWifiInjector; 174 @Mock WifiContext mContext; 175 @Mock WifiResourceCache mWifiResourceCache; 176 @Mock WifiNative mWifiNative; 177 @Mock WifiApConfigStore mWifiApConfigStore; 178 @Mock ConcreteClientModeManager mClientModeManager; 179 @Mock SoftApManager mSoftApManager; 180 @Mock DefaultClientModeManager mDefaultClientModeManager; 181 @Mock BatteryStatsManager mBatteryStats; 182 @Mock SelfRecovery mSelfRecovery; 183 @Mock WifiDiagnostics mWifiDiagnostics; 184 @Mock ScanRequestProxy mScanRequestProxy; 185 @Mock FrameworkFacade mFacade; 186 @Mock WifiSettingsStore mSettingsStore; 187 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 188 @Mock SoftApCapability mSoftApCapability; 189 @Mock ActiveModeWarden.ModeChangeCallback mModeChangeCallback; 190 @Mock ActiveModeWarden.PrimaryClientModeManagerChangedCallback mPrimaryChangedCallback; 191 @Mock WifiMetrics mWifiMetrics; 192 @Mock ISubsystemRestartCallback mSubsystemRestartCallback; 193 @Mock ExternalScoreUpdateObserverProxy mExternalScoreUpdateObserverProxy; 194 @Mock DppManager mDppManager; 195 @Mock SarManager mSarManager; 196 @Mock HalDeviceManager mHalDeviceManager; 197 @Mock UserManager mUserManager; 198 @Mock PackageManager mPackageManager; 199 @Mock Network mNetwork; 200 @Mock LocalLog mLocalLog; 201 @Mock WifiSettingsConfigStore mSettingsConfigStore; 202 @Mock LastCallerInfoManager mLastCallerInfoManager; 203 @Mock WifiGlobals mWifiGlobals; 204 @Mock WifiConnectivityManager mWifiConnectivityManager; 205 @Mock WifiConfigManager mWifiConfigManager; 206 207 Listener<ConcreteClientModeManager> mClientListener; 208 Listener<SoftApManager> mSoftApListener; 209 WifiServiceImpl.SoftApCallbackInternal mSoftApManagerCallback; 210 SoftApModeConfiguration mSoftApConfig; 211 @Mock WifiServiceImpl.SoftApCallbackInternal mSoftApStateMachineCallback; 212 @Mock WifiServiceImpl.SoftApCallbackInternal mLohsStateMachineCallback; 213 WifiNative.StatusListener mWifiNativeStatusListener; 214 ActiveModeWarden mActiveModeWarden; 215 private SoftApInfo mTestSoftApInfo; 216 217 final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor = 218 ArgumentCaptor.forClass(WifiNative.StatusListener.class); 219 220 private BroadcastReceiver mEmergencyCallbackModeChangedBr; 221 private BroadcastReceiver mEmergencyCallStateChangedBr; 222 private StaticMockitoSession mStaticMockSession; 223 224 /** 225 * Set up the test environment. 226 */ 227 @Before setUp()228 public void setUp() throws Exception { 229 Log.d(TAG, "Setting up ..."); 230 231 MockitoAnnotations.initMocks(this); 232 mStaticMockSession = mockitoSession() 233 .mockStatic(WifiInjector.class) 234 .startMocking(); 235 mLooper = new TestLooper(); 236 237 when(WifiInjector.getInstance()).thenReturn(mWifiInjector); 238 when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy); 239 when(mWifiInjector.getSarManager()).thenReturn(mSarManager); 240 when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager); 241 when(mWifiInjector.getUserManager()).thenReturn(mUserManager); 242 when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog); 243 when(mWifiInjector.getWifiConnectivityManager()).thenReturn(mWifiConnectivityManager); 244 when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager); 245 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 246 when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME); 247 when(mContext.getResourceCache()).thenReturn(mWifiResourceCache); 248 when(mSoftApManager.getRole()).thenReturn(ROLE_SOFTAP_TETHERED); 249 250 when(mWifiResourceCache.getString(R.string.wifi_localhotspot_configure_ssid_default)) 251 .thenReturn("AndroidShare"); 252 when(mWifiResourceCache.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay)) 253 .thenReturn(TEST_WIFI_RECOVERY_DELAY_MS); 254 when(mWifiResourceCache.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) 255 .thenReturn(false); 256 when(mWifiResourceCache.getBoolean(R.bool.config_wifi_turn_off_during_emergency_call)) 257 .thenReturn(true); 258 259 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 260 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 261 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 262 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 263 when(mFacade.getSettingsWorkSource(mContext)).thenReturn(SETTINGS_WORKSOURCE); 264 when(mContext.getPackageManager()).thenReturn(mPackageManager); 265 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(true); 266 when(mWifiInjector.getSettingsConfigStore()).thenReturn(mSettingsConfigStore); 267 when(mWifiInjector.getLastCallerInfoManager()).thenReturn(mLastCallerInfoManager); 268 when(mSettingsConfigStore.get( 269 eq(WIFI_NATIVE_SUPPORTED_STA_BANDS))).thenReturn( 270 TEST_SUPPORTED_BANDS); 271 // Default force that WPA Personal is deprecated since the feature set is opposite to the 272 // API value. 273 when(mWifiGlobals.isWpaPersonalDeprecated()).thenReturn(true); 274 doAnswer(new Answer<ClientModeManager>() { 275 public ClientModeManager answer(InvocationOnMock invocation) { 276 Object[] args = invocation.getArguments(); 277 mClientListener = (Listener<ConcreteClientModeManager>) args[0]; 278 return mClientModeManager; 279 } 280 }).when(mWifiInjector).makeClientModeManager( 281 any(Listener.class), any(), any(), anyBoolean()); 282 doAnswer(new Answer<SoftApManager>() { 283 public SoftApManager answer(InvocationOnMock invocation) { 284 Object[] args = invocation.getArguments(); 285 mSoftApListener = (Listener<SoftApManager>) args[0]; 286 mSoftApManagerCallback = (WifiServiceImpl.SoftApCallbackInternal) args[1]; 287 mSoftApConfig = (SoftApModeConfiguration) args[2]; 288 return mSoftApManager; 289 } 290 }).when(mWifiInjector).makeSoftApManager(any(Listener.class), 291 any(WifiServiceImpl.SoftApCallbackInternal.class), any(), any(), any(), 292 anyBoolean()); 293 when(mWifiNative.initialize()).thenReturn(true); 294 when(mWifiNative.getSupportedFeatureSet(isNull())).thenReturn(new BitSet()); 295 when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn(new BitSet()); 296 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(true); 297 298 mActiveModeWarden = createActiveModeWarden(); 299 mActiveModeWarden.start(); 300 mLooper.dispatchAll(); 301 302 verify(mWifiMetrics).noteWifiEnabledDuringBoot(false); 303 verify(mWifiGlobals).setD2dStaConcurrencySupported(false); 304 verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture()); 305 verify(mWifiNative).initialize(); 306 mWifiNativeStatusListener = mStatusListenerCaptor.getValue(); 307 308 mActiveModeWarden.registerSoftApCallback(mSoftApStateMachineCallback); 309 mActiveModeWarden.registerLohsCallback(mLohsStateMachineCallback); 310 mActiveModeWarden.registerModeChangeCallback(mModeChangeCallback); 311 mActiveModeWarden.registerPrimaryClientModeManagerChangedCallback(mPrimaryChangedCallback); 312 when(mSubsystemRestartCallback.asBinder()).thenReturn(Mockito.mock(IBinder.class)); 313 mActiveModeWarden.registerSubsystemRestartCallback(mSubsystemRestartCallback); 314 mTestSoftApInfo = new SoftApInfo(); 315 mTestSoftApInfo.setFrequency(TEST_AP_FREQUENCY); 316 mTestSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); 317 318 ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = 319 ArgumentCaptor.forClass(BroadcastReceiver.class); 320 verify(mContext).registerReceiver( 321 bcastRxCaptor.capture(), 322 argThat(filter -> 323 filter.hasAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED))); 324 mEmergencyCallbackModeChangedBr = bcastRxCaptor.getValue(); 325 326 verify(mContext).registerReceiver( 327 bcastRxCaptor.capture(), 328 argThat(filter -> 329 filter.hasAction(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED))); 330 mEmergencyCallStateChangedBr = bcastRxCaptor.getValue(); 331 } 332 createActiveModeWarden()333 private ActiveModeWarden createActiveModeWarden() { 334 ActiveModeWarden warden = new ActiveModeWarden( 335 mWifiInjector, 336 mLooper.getLooper(), 337 mWifiNative, 338 mDefaultClientModeManager, 339 mBatteryStats, 340 mWifiDiagnostics, 341 mContext, 342 mSettingsStore, 343 mFacade, 344 mWifiPermissionsUtil, 345 mWifiMetrics, 346 mExternalScoreUpdateObserverProxy, 347 mDppManager, 348 mWifiGlobals); 349 // SelfRecovery is created in WifiInjector after ActiveModeWarden, so getSelfRecovery() 350 // returns null when constructing ActiveModeWarden. 351 when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); 352 when(mContext.getPackageManager()).thenReturn(mPackageManager); 353 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(true); 354 warden.setWifiStateForApiCalls(WIFI_STATE_ENABLED); 355 return warden; 356 } 357 358 /** 359 * Clean up after tests - explicitly set tested object to null. 360 */ 361 @After cleanUp()362 public void cleanUp() throws Exception { 363 mActiveModeWarden = null; 364 mStaticMockSession.finishMocking(); 365 mLooper.dispatchAll(); 366 } 367 emergencyCallbackModeChanged(boolean enabled)368 private void emergencyCallbackModeChanged(boolean enabled) { 369 Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); 370 intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, enabled); 371 mEmergencyCallbackModeChangedBr.onReceive(mContext, intent); 372 } 373 emergencyCallStateChanged(boolean enabled)374 private void emergencyCallStateChanged(boolean enabled) { 375 Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED); 376 intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, enabled); 377 mEmergencyCallStateChangedBr.onReceive(mContext, intent); 378 } 379 enterClientModeActiveState()380 private void enterClientModeActiveState() throws Exception { 381 enterClientModeActiveState(false); 382 } 383 384 /** 385 * Helper method to enter the EnabledState and set ClientModeManager in ConnectMode. 386 * @param isClientModeSwitch true if switching from another mode, false if creating a new one 387 */ enterClientModeActiveState(boolean isClientModeSwitch)388 private void enterClientModeActiveState(boolean isClientModeSwitch) throws Exception { 389 enterClientModeActiveState(isClientModeSwitch, TEST_FEATURE_SET); 390 } 391 392 /** 393 * Helper method with tested feature set to enter the EnabledState and set ClientModeManager 394 * in ConnectMode. 395 * 396 * @param isClientModeSwitch true if switching from another mode, false if creating a new one 397 * @param testFeatureSet a customized feature set to test 398 */ enterClientModeActiveState(boolean isClientModeSwitch, BitSet testFeatureSet)399 private void enterClientModeActiveState(boolean isClientModeSwitch, BitSet testFeatureSet) 400 throws Exception { 401 String fromState = mActiveModeWarden.getCurrentMode(); 402 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 403 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 404 mLooper.dispatchAll(); 405 assertNull(mActiveModeWarden.getCurrentNetwork()); 406 407 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 408 when(mClientModeManager.getCurrentNetwork()).thenReturn(mNetwork); 409 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)) 410 .thenReturn(testFeatureSet); 411 // ClientModeManager starts in SCAN_ONLY role. 412 mClientListener.onRoleChanged(mClientModeManager); 413 mLooper.dispatchAll(); 414 415 assertInEnabledState(); 416 if (!isClientModeSwitch) { 417 verify(mWifiInjector).makeClientModeManager( 418 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 419 } else { 420 verify(mClientModeManager).setRole(ROLE_CLIENT_PRIMARY, SETTINGS_WORKSOURCE); 421 } 422 verify(mScanRequestProxy, times(1)).enableScanning(true, true); 423 if (fromState.equals(DISABLED_STATE_STRING)) { 424 verify(mBatteryStats).reportWifiOn(); 425 } 426 for (int i = 0; i < 3; i++) { 427 mActiveModeWarden.updateClientScanModeAfterCountryCodeUpdate(TEST_COUNTRYCODE); 428 } 429 verify(mClientModeManager, atLeastOnce()).getInterfaceName(); 430 verify(mWifiNative, atLeastOnce()).getSupportedFeatureSet(WIFI_IFACE_NAME); 431 assertTrue(testFeatureSet.equals(mActiveModeWarden.getSupportedFeatureSet())); 432 verify(mScanRequestProxy, times(4)).enableScanning(true, true); 433 assertEquals(mClientModeManager, mActiveModeWarden.getPrimaryClientModeManager()); 434 verify(mModeChangeCallback).onActiveModeManagerRoleChanged(mClientModeManager); 435 assertEquals(mNetwork, mActiveModeWarden.getCurrentNetwork()); 436 } 437 enterScanOnlyModeActiveState()438 private void enterScanOnlyModeActiveState() throws Exception { 439 enterScanOnlyModeActiveState(false); 440 } 441 442 /** 443 * Helper method to enter the EnabledState and set ClientModeManager in ScanOnlyMode. 444 */ enterScanOnlyModeActiveState(boolean isClientModeSwitch)445 private void enterScanOnlyModeActiveState(boolean isClientModeSwitch) throws Exception { 446 String fromState = mActiveModeWarden.getCurrentMode(); 447 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 448 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 449 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 450 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 451 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 452 mLooper.dispatchAll(); 453 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY); 454 when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME); 455 when(mClientModeManager.getCurrentNetwork()).thenReturn(null); 456 when(mWifiNative.getSupportedFeatureSet(null)).thenReturn(TEST_FEATURE_SET); 457 if (!isClientModeSwitch) { 458 mClientListener.onStarted(mClientModeManager); 459 mLooper.dispatchAll(); 460 verify(mWifiInjector).makeClientModeManager( 461 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_SCAN_ONLY), anyBoolean()); 462 verify(mModeChangeCallback).onActiveModeManagerAdded(mClientModeManager); 463 } else { 464 mClientListener.onRoleChanged(mClientModeManager); 465 mLooper.dispatchAll(); 466 verify(mClientModeManager).setRole(ROLE_CLIENT_SCAN_ONLY, INTERNAL_REQUESTOR_WS); 467 // If switching from client mode back to scan only mode, role change would have been 468 // called once before when transitioning from scan only mode to client mode. 469 // Verify that it was called again. 470 verify(mModeChangeCallback, times(2)) 471 .onActiveModeManagerRoleChanged(mClientModeManager); 472 verify(mWifiNative, atLeastOnce()).getSupportedFeatureSet(null); 473 assertTrue(TEST_FEATURE_SET.equals(mActiveModeWarden.getSupportedFeatureSet())); 474 } 475 assertInEnabledState(); 476 verify(mScanRequestProxy).enableScanning(true, false); 477 if (fromState.equals(DISABLED_STATE_STRING)) { 478 verify(mBatteryStats).reportWifiOn(); 479 } 480 verify(mBatteryStats).reportWifiState(BatteryStatsManager.WIFI_STATE_OFF_SCANNING, null); 481 assertEquals(mClientModeManager, mActiveModeWarden.getScanOnlyClientModeManager()); 482 } 483 enterSoftApActiveMode()484 private void enterSoftApActiveMode() throws Exception { 485 enterSoftApActiveMode( 486 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 487 mSoftApCapability, TEST_COUNTRYCODE, null)); 488 } 489 490 private int mTimesCreatedSoftApManager = 1; 491 492 /** 493 * Helper method to activate SoftApManager. 494 * 495 * This method puts the test object into the correct state and verifies steps along the way. 496 */ enterSoftApActiveMode(SoftApModeConfiguration softApConfig)497 private void enterSoftApActiveMode(SoftApModeConfiguration softApConfig) throws Exception { 498 String fromState = mActiveModeWarden.getCurrentMode(); 499 SoftApRole softApRole = softApConfig.getTargetMode() == WifiManager.IFACE_IP_MODE_TETHERED 500 ? ROLE_SOFTAP_TETHERED : ROLE_SOFTAP_LOCAL_ONLY; 501 mActiveModeWarden.startSoftAp(softApConfig, TEST_WORKSOURCE); 502 mLooper.dispatchAll(); 503 when(mSoftApManager.getRole()).thenReturn(softApRole); 504 when(mSoftApManager.getSoftApModeConfiguration()).thenReturn(softApConfig); 505 mSoftApListener.onStarted(mSoftApManager); 506 mLooper.dispatchAll(); 507 508 assertInEnabledState(); 509 assertThat(softApConfig).isEqualTo(mSoftApConfig); 510 verify(mWifiInjector, times(mTimesCreatedSoftApManager)).makeSoftApManager( 511 any(), any(), any(), eq(TEST_WORKSOURCE), eq(softApRole), anyBoolean()); 512 mTimesCreatedSoftApManager++; 513 if (fromState.equals(DISABLED_STATE_STRING)) { 514 verify(mBatteryStats, atLeastOnce()).reportWifiOn(); 515 } 516 if (softApRole == ROLE_SOFTAP_TETHERED) { 517 assertEquals(mSoftApManager, mActiveModeWarden.getTetheredSoftApManager()); 518 assertNull(mActiveModeWarden.getLocalOnlySoftApManager()); 519 } else { 520 assertEquals(mSoftApManager, mActiveModeWarden.getLocalOnlySoftApManager()); 521 assertNull(mActiveModeWarden.getTetheredSoftApManager()); 522 } 523 verify(mModeChangeCallback).onActiveModeManagerAdded(mSoftApManager); 524 } 525 enterStaDisabledMode(boolean isSoftApModeManagerActive)526 private void enterStaDisabledMode(boolean isSoftApModeManagerActive) { 527 String fromState = mActiveModeWarden.getCurrentMode(); 528 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 529 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 530 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 531 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 532 mLooper.dispatchAll(); 533 if (mClientListener != null) { 534 mClientListener.onStopped(mClientModeManager); 535 mLooper.dispatchAll(); 536 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 537 } 538 539 if (isSoftApModeManagerActive) { 540 assertInEnabledState(); 541 } else { 542 assertInDisabledState(); 543 } 544 if (fromState.equals(ENABLED_STATE_STRING)) { 545 verify(mScanRequestProxy).enableScanning(false, false); 546 } 547 // Ensure we return the default client mode manager when wifi is off. 548 assertEquals(mDefaultClientModeManager, mActiveModeWarden.getPrimaryClientModeManager()); 549 } 550 shutdownWifi()551 private void shutdownWifi() { 552 mActiveModeWarden.recoveryDisableWifi(); 553 mLooper.dispatchAll(); 554 } 555 assertInEnabledState()556 private void assertInEnabledState() { 557 assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(ENABLED_STATE_STRING); 558 } 559 assertInDisabledState()560 private void assertInDisabledState() { 561 assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(DISABLED_STATE_STRING); 562 } 563 564 /** 565 * Emergency mode is a sub-mode within each main state (ScanOnly, Client, DisabledState). 566 */ assertInEmergencyMode()567 private void assertInEmergencyMode() { 568 assertThat(mActiveModeWarden.isInEmergencyMode()).isTrue(); 569 } 570 assertNotInEmergencyMode()571 private void assertNotInEmergencyMode() { 572 assertThat(mActiveModeWarden.isInEmergencyMode()).isFalse(); 573 } 574 575 /** 576 * Counts the number of times a void method was called on a mock. 577 * 578 * Void methods cannot be passed to Mockito.mockingDetails(). Thus we have to use method name 579 * matching instead. 580 */ getMethodInvocationCount(Object mock, String methodName)581 private static int getMethodInvocationCount(Object mock, String methodName) { 582 long count = mockingDetails(mock).getInvocations() 583 .stream() 584 .filter(invocation -> methodName.equals(invocation.getMethod().getName())) 585 .count(); 586 return (int) count; 587 } 588 589 /** 590 * Counts the number of times a non-void method was called on a mock. 591 * 592 * For non-void methods, can pass the method call literal directly: 593 * e.g. getMethodInvocationCount(mock.method()); 594 */ getMethodInvocationCount(Object mockMethod)595 private static int getMethodInvocationCount(Object mockMethod) { 596 return mockingDetails(mockMethod).getInvocations().size(); 597 } 598 assertWifiShutDown(Runnable r)599 private void assertWifiShutDown(Runnable r) { 600 assertWifiShutDown(r, 1); 601 } 602 603 /** 604 * Asserts that the runnable r has shut down wifi properly. 605 * 606 * @param r runnable that will shut down wifi 607 * @param times expected number of times that <code>r</code> shut down wifi 608 */ assertWifiShutDown(Runnable r, int times)609 private void assertWifiShutDown(Runnable r, int times) { 610 // take snapshot of ActiveModeManagers 611 Collection<ActiveModeManager> activeModeManagers = 612 mActiveModeWarden.getActiveModeManagers(); 613 614 List<Integer> expectedStopInvocationCounts = activeModeManagers 615 .stream() 616 .map(manager -> getMethodInvocationCount(manager, "stop") + times) 617 .collect(Collectors.toList()); 618 619 r.run(); 620 621 List<Integer> actualStopInvocationCounts = activeModeManagers 622 .stream() 623 .map(manager -> getMethodInvocationCount(manager, "stop")) 624 .collect(Collectors.toList()); 625 626 String managerNames = activeModeManagers.stream() 627 .map(manager -> manager.getClass().getCanonicalName()) 628 .collect(Collectors.joining(", ", "[", "]")); 629 630 assertWithMessage(managerNames).that(actualStopInvocationCounts) 631 .isEqualTo(expectedStopInvocationCounts); 632 } 633 assertEnteredEcmMode(Runnable r)634 private void assertEnteredEcmMode(Runnable r) { 635 assertEnteredEcmMode(r, 1); 636 } 637 638 /** 639 * Asserts that the runnable r has entered ECM state properly. 640 * 641 * @param r runnable that will enter ECM 642 * @param times expected number of times that <code>r</code> shut down wifi 643 */ assertEnteredEcmMode(Runnable r, int times)644 private void assertEnteredEcmMode(Runnable r, int times) { 645 // take snapshot of ActiveModeManagers 646 Collection<ActiveModeManager> activeModeManagers = 647 mActiveModeWarden.getActiveModeManagers(); 648 649 boolean disableWifiInEcm = mFacade.getConfigWiFiDisableInECBM(mContext); 650 651 List<Integer> expectedStopInvocationCounts = activeModeManagers.stream() 652 .map(manager -> { 653 int initialCount = getMethodInvocationCount(manager, "stop"); 654 // carrier config enabled, all mode managers should have been shut down once 655 int count = disableWifiInEcm ? initialCount + times : initialCount; 656 if (manager instanceof SoftApManager) { 657 // expect SoftApManager.close() to be called 658 return count + times; 659 } else { 660 // don't expect other Managers close() to be called 661 return count; 662 } 663 }) 664 .collect(Collectors.toList()); 665 666 r.run(); 667 668 assertInEmergencyMode(); 669 670 List<Integer> actualStopInvocationCounts = activeModeManagers.stream() 671 .map(manager -> getMethodInvocationCount(manager, "stop")) 672 .collect(Collectors.toList()); 673 674 String managerNames = activeModeManagers.stream() 675 .map(manager -> manager.getClass().getCanonicalName()) 676 .collect(Collectors.joining(", ", "[", "]")); 677 678 assertWithMessage(managerNames).that(actualStopInvocationCounts) 679 .isEqualTo(expectedStopInvocationCounts); 680 } 681 682 /** Test that after starting up, ActiveModeWarden is in the DisabledState State. */ 683 @Test testDisabledStateAtStartup()684 public void testDisabledStateAtStartup() { 685 assertInDisabledState(); 686 } 687 688 /** 689 * Test that ActiveModeWarden properly enters the EnabledState (in ScanOnlyMode) from the 690 * DisabledState state. 691 */ 692 @Test testEnterScanOnlyModeFromDisabled()693 public void testEnterScanOnlyModeFromDisabled() throws Exception { 694 enterScanOnlyModeActiveState(); 695 } 696 697 /** 698 * Test that ActiveModeWarden enables hidden network scanning in scan-only-mode 699 * if configured to do. 700 */ 701 @Test testScanOnlyModeScanHiddenNetworks()702 public void testScanOnlyModeScanHiddenNetworks() throws Exception { 703 when(mWifiResourceCache.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) 704 .thenReturn(true); 705 706 mActiveModeWarden = createActiveModeWarden(); 707 mActiveModeWarden.start(); 708 mLooper.dispatchAll(); 709 710 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY); 711 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 712 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 713 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 714 mLooper.dispatchAll(); 715 mClientListener.onStarted(mClientModeManager); 716 mLooper.dispatchAll(); 717 718 assertInEnabledState(); 719 verify(mWifiInjector).makeClientModeManager( 720 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_SCAN_ONLY), anyBoolean()); 721 verify(mScanRequestProxy).enableScanning(true, true); 722 } 723 724 /** 725 * Test that ActiveModeWarden properly starts the SoftApManager from the 726 * DisabledState state. 727 */ 728 @Test testEnterSoftApModeFromDisabled()729 public void testEnterSoftApModeFromDisabled() throws Exception { 730 enterSoftApActiveMode(); 731 } 732 733 /** 734 * Test that ActiveModeWarden properly starts the SoftApManager from another state. 735 */ 736 @Test testEnterSoftApModeFromDifferentState()737 public void testEnterSoftApModeFromDifferentState() throws Exception { 738 enterClientModeActiveState(); 739 assertInEnabledState(); 740 reset(mBatteryStats, mScanRequestProxy); 741 enterSoftApActiveMode(); 742 } 743 744 /** 745 * Test that we can disable wifi fully from the EnabledState (in ScanOnlyMode). 746 */ 747 @Test testDisableWifiFromScanOnlyModeActiveState()748 public void testDisableWifiFromScanOnlyModeActiveState() throws Exception { 749 enterScanOnlyModeActiveState(); 750 751 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 752 mActiveModeWarden.scanAlwaysModeChanged(); 753 mLooper.dispatchAll(); 754 mClientListener.onStopped(mClientModeManager); 755 mLooper.dispatchAll(); 756 757 verify(mClientModeManager).stop(); 758 verify(mBatteryStats).reportWifiOff(); 759 assertInDisabledState(); 760 } 761 762 /** 763 * Test that we can disable wifi when SoftApManager is active and not impact softap. 764 */ 765 @Test testDisableWifiFromSoftApModeActiveStateDoesNotStopSoftAp()766 public void testDisableWifiFromSoftApModeActiveStateDoesNotStopSoftAp() throws Exception { 767 enterSoftApActiveMode(); 768 enterScanOnlyModeActiveState(); 769 770 reset(mDefaultClientModeManager); 771 enterStaDisabledMode(true); 772 verify(mSoftApManager, never()).stop(); 773 verify(mBatteryStats, never()).reportWifiOff(); 774 } 775 776 /** 777 * Test that we can switch from the EnabledState (in ScanOnlyMode) to another mode. 778 */ 779 @Test testSwitchModeWhenScanOnlyModeActiveState()780 public void testSwitchModeWhenScanOnlyModeActiveState() throws Exception { 781 enterScanOnlyModeActiveState(); 782 783 reset(mBatteryStats, mScanRequestProxy); 784 enterClientModeActiveState(true); 785 mLooper.dispatchAll(); 786 } 787 788 /** 789 * Test that we can switch from the EnabledState (in ConnectMode) to another mode. 790 */ 791 @Test testSwitchModeWhenConnectModeActiveState()792 public void testSwitchModeWhenConnectModeActiveState() throws Exception { 793 enterClientModeActiveState(); 794 795 verify(mPrimaryChangedCallback).onChange(null, mClientModeManager); 796 797 reset(mBatteryStats, mScanRequestProxy); 798 enterScanOnlyModeActiveState(true); 799 mLooper.dispatchAll(); 800 801 verify(mPrimaryChangedCallback).onChange(mClientModeManager, null); 802 } 803 804 /** 805 * Test that wifi toggle switching the primary to scan only mode will also remove the additional 806 * CMMs. 807 */ 808 @Test testSwitchFromConnectModeToScanOnlyModeRemovesAdditionalCMMs()809 public void testSwitchFromConnectModeToScanOnlyModeRemovesAdditionalCMMs() throws Exception { 810 // Ensure that we can create more client ifaces. 811 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 812 when(mWifiResourceCache.getBoolean( 813 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 814 .thenReturn(true); 815 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 816 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 817 818 // request for an additional CMM 819 ConcreteClientModeManager additionalClientModeManager = 820 mock(ConcreteClientModeManager.class); 821 ExternalClientModeManagerRequestListener externalRequestListener = mock( 822 ExternalClientModeManagerRequestListener.class); 823 Listener<ConcreteClientModeManager> additionalClientListener = 824 requestAdditionalClientModeManager(ROLE_CLIENT_SECONDARY_TRANSIENT, 825 additionalClientModeManager, externalRequestListener, TEST_SSID_2, 826 TEST_BSSID_2); 827 828 // Verify that there exists both a primary and a secondary transient CMM 829 List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers(); 830 assertEquals(2, currentCMMs.size()); 831 assertTrue(currentCMMs.stream().anyMatch(cmm -> cmm.getRole() == ROLE_CLIENT_PRIMARY)); 832 assertTrue(currentCMMs.stream().anyMatch( 833 cmm -> cmm.getRole() == ROLE_CLIENT_SECONDARY_TRANSIENT)); 834 verify(mWifiConnectivityManager, never()).resetOnWifiDisable(); 835 836 InOrder inOrder = inOrder(additionalClientModeManager, mClientModeManager); 837 // disable wifi and switch primary CMM to scan only mode 838 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 839 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 840 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 841 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 842 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 843 mLooper.dispatchAll(); 844 845 // Verify that we first stop the additional CMM and then switch the primary to scan only 846 // mode 847 inOrder.verify(additionalClientModeManager).stop(); 848 inOrder.verify(mClientModeManager).setRole(ROLE_CLIENT_SCAN_ONLY, INTERNAL_REQUESTOR_WS); 849 verify(mWifiConnectivityManager).resetOnWifiDisable(); 850 } 851 852 /** 853 * Verify that when there are only secondary CMMs available, the user toggling wifi on will 854 * create a new primary CMM. 855 */ 856 @Test testToggleWifiWithOnlySecondaryCmmsCreatesPrimaryOrScanOnlyCmm()857 public void testToggleWifiWithOnlySecondaryCmmsCreatesPrimaryOrScanOnlyCmm() throws Exception { 858 enterClientModeActiveState(); 859 verify(mWifiInjector, times(1)).makeClientModeManager( 860 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 861 862 // toggling wifi on again should be no-op when primary is already available 863 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 864 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 865 mLooper.dispatchAll(); 866 867 verify(mWifiInjector, times(1)).makeClientModeManager( 868 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 869 870 // Make the primary CMM change to local only secondary role. 871 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 872 mClientListener.onRoleChanged(mClientModeManager); 873 mLooper.dispatchAll(); 874 875 // Verify that there only exists the ROLE_CLIENT_LOCAL_ONLY CMM. 876 List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers(); 877 assertEquals(1, currentCMMs.size()); 878 assertTrue(currentCMMs.get(0).getRole() == ROLE_CLIENT_LOCAL_ONLY); 879 880 // verify wifi toggling on should recreate the primary CMM 881 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 882 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 883 mLooper.dispatchAll(); 884 885 verify(mWifiInjector, times(2)).makeClientModeManager( 886 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 887 } 888 889 @Test testClientModeChangeRoleDuringTransition()890 public void testClientModeChangeRoleDuringTransition() throws Exception { 891 enterClientModeActiveState(); 892 verify(mWifiInjector).makeClientModeManager( 893 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 894 895 // Simulate the primary not fully started by making the role null and targetRole primary. 896 when(mClientModeManager.getRole()).thenReturn(null); 897 when(mClientModeManager.getTargetRole()).thenReturn(ROLE_CLIENT_PRIMARY); 898 List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers(); 899 assertEquals(1, currentCMMs.size()); 900 ConcreteClientModeManager currentCmm = (ConcreteClientModeManager) currentCMMs.get(0); 901 assertTrue(currentCmm.getTargetRole() == ROLE_CLIENT_PRIMARY); 902 903 // toggle wifi off while wifi scanning is on 904 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 905 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 906 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 907 mLooper.dispatchAll(); 908 909 // expect transition to scan only mode 910 verify(mClientModeManager).setRole(eq(ROLE_CLIENT_SCAN_ONLY), any()); 911 } 912 913 @Test testPrimaryNotCreatedTwice()914 public void testPrimaryNotCreatedTwice() throws Exception { 915 enterClientModeActiveState(); 916 verify(mWifiInjector).makeClientModeManager( 917 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 918 919 // toggling wifi on again should be no-op when primary is already available 920 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 921 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 922 mLooper.dispatchAll(); 923 924 verify(mWifiInjector).makeClientModeManager( 925 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 926 927 // Simulate the primary not fully started by making the role null and targetRole primary. 928 when(mClientModeManager.getRole()).thenReturn(null); 929 when(mClientModeManager.getTargetRole()).thenReturn(ROLE_CLIENT_PRIMARY); 930 931 // Verify that there is no primary, but there is a CMM with targetRole as primary. 932 List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers(); 933 assertEquals(1, currentCMMs.size()); 934 ConcreteClientModeManager currentCmm = (ConcreteClientModeManager) currentCMMs.get(0); 935 assertTrue(currentCmm.getRole() == null); 936 assertTrue(currentCmm.getTargetRole() == ROLE_CLIENT_PRIMARY); 937 938 // verify wifi toggling on should not create another primary CMM. 939 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 940 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 941 mLooper.dispatchAll(); 942 943 verify(mWifiInjector).makeClientModeManager( 944 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 945 } 946 947 /** 948 * Reentering EnabledState should be a NOP. 949 */ 950 @Test testReenterClientModeActiveStateIsNop()951 public void testReenterClientModeActiveStateIsNop() throws Exception { 952 enterClientModeActiveState(); 953 verify(mWifiInjector, times(1)).makeClientModeManager( 954 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 955 956 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 957 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 958 mLooper.dispatchAll(); 959 // Should not start again. 960 verify(mWifiInjector, times(1)).makeClientModeManager( 961 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 962 } 963 964 /** 965 * Test that we can switch mode when SoftApManager is active to another mode. 966 */ 967 @Test testSwitchModeWhenSoftApActiveMode()968 public void testSwitchModeWhenSoftApActiveMode() throws Exception { 969 enterSoftApActiveMode(); 970 971 reset(mWifiNative); 972 973 enterClientModeActiveState(); 974 mLooper.dispatchAll(); 975 verify(mSoftApManager, never()).stop(); 976 assertInEnabledState(); 977 verify(mWifiNative, never()).teardownAllInterfaces(); 978 } 979 980 /** 981 * Test that we activate SoftApModeManager if we are already in DisabledState due to 982 * a failure. 983 */ 984 @Test testEnterSoftApModeActiveWhenAlreadyInSoftApMode()985 public void testEnterSoftApModeActiveWhenAlreadyInSoftApMode() throws Exception { 986 enterSoftApActiveMode(); 987 // now inject failure through the SoftApManager.Listener 988 mSoftApListener.onStartFailure(mSoftApManager); 989 mLooper.dispatchAll(); 990 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 991 assertInDisabledState(); 992 // clear the first call to start SoftApManager 993 reset(mSoftApManager, mBatteryStats, mModeChangeCallback); 994 995 enterSoftApActiveMode(); 996 } 997 998 /** 999 * Test that we return to the DisabledState after a failure is reported when in the 1000 * EnabledState. 1001 */ 1002 @Test testScanOnlyModeFailureWhenActive()1003 public void testScanOnlyModeFailureWhenActive() throws Exception { 1004 enterScanOnlyModeActiveState(); 1005 // now inject a failure through the ScanOnlyModeManager.Listener 1006 mClientListener.onStartFailure(mClientModeManager); 1007 mLooper.dispatchAll(); 1008 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 1009 assertInDisabledState(); 1010 verify(mBatteryStats).reportWifiOff(); 1011 } 1012 1013 /** 1014 * Test that we return to the DisabledState after a failure is reported when 1015 * SoftApManager is active. 1016 */ 1017 @Test testSoftApFailureWhenActive()1018 public void testSoftApFailureWhenActive() throws Exception { 1019 enterSoftApActiveMode(); 1020 // now inject failure through the SoftApManager.Listener 1021 mSoftApListener.onStartFailure(mSoftApManager); 1022 mLooper.dispatchAll(); 1023 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 1024 verify(mBatteryStats).reportWifiOff(); 1025 } 1026 1027 /** 1028 * Test that we return to the DisabledState after the ClientModeManager running in ScanOnlyMode 1029 * is stopped. 1030 */ 1031 @Test testScanOnlyModeDisabledWhenActive()1032 public void testScanOnlyModeDisabledWhenActive() throws Exception { 1033 enterScanOnlyModeActiveState(); 1034 1035 // now inject the stop message through the ScanOnlyModeManager.Listener 1036 mClientListener.onStopped(mClientModeManager); 1037 mLooper.dispatchAll(); 1038 1039 assertInDisabledState(); 1040 verify(mBatteryStats).reportWifiOff(); 1041 } 1042 1043 /** 1044 * Test that we return to the DisabledState after the SoftApManager is stopped. 1045 */ 1046 @Test testSoftApDisabledWhenActive()1047 public void testSoftApDisabledWhenActive() throws Exception { 1048 enterSoftApActiveMode(); 1049 reset(mWifiNative); 1050 // now inject failure through the SoftApManager.Listener 1051 mSoftApListener.onStartFailure(mSoftApManager); 1052 mLooper.dispatchAll(); 1053 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 1054 verify(mBatteryStats).reportWifiOff(); 1055 verifyNoMoreInteractions(mWifiNative); 1056 } 1057 1058 /** 1059 * Verifies that SoftApStateChanged event is being passed from SoftApManager to WifiServiceImpl 1060 */ 1061 @Test callsWifiServiceCallbackOnSoftApStateChanged()1062 public void callsWifiServiceCallbackOnSoftApStateChanged() throws Exception { 1063 enterSoftApActiveMode(); 1064 1065 mSoftApListener.onStarted(mSoftApManager); 1066 SoftApState softApState = new SoftApState( 1067 WifiManager.WIFI_AP_STATE_ENABLED, 0, null, null); 1068 mSoftApManagerCallback.onStateChanged(softApState); 1069 mLooper.dispatchAll(); 1070 1071 verify(mSoftApStateMachineCallback).onStateChanged(softApState); 1072 } 1073 1074 /** 1075 * Verifies that SoftApStateChanged event isn't passed to WifiServiceImpl for LOHS, 1076 * so the state change for LOHS doesn't affect Wifi Tethering indication. 1077 */ 1078 @Test doesntCallWifiServiceCallbackOnLOHSStateChanged()1079 public void doesntCallWifiServiceCallbackOnLOHSStateChanged() throws Exception { 1080 enterSoftApActiveMode(new SoftApModeConfiguration( 1081 WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null, mSoftApCapability, TEST_COUNTRYCODE, 1082 null)); 1083 1084 mSoftApListener.onStarted(mSoftApManager); 1085 SoftApState softApState = new SoftApState( 1086 WifiManager.WIFI_AP_STATE_ENABLED, 0, null, null); 1087 mSoftApManagerCallback.onStateChanged(softApState); 1088 mLooper.dispatchAll(); 1089 1090 verify(mSoftApStateMachineCallback, never()).onStateChanged(softApState); 1091 verify(mSoftApStateMachineCallback, never()).onConnectedClientsOrInfoChanged(any(), 1092 any(), anyBoolean()); 1093 } 1094 1095 /** 1096 * Verifies that ConnectedClientsOrInfoChanged event is being passed from SoftApManager 1097 * to WifiServiceImpl 1098 */ 1099 @Test callsWifiServiceCallbackOnSoftApConnectedClientsChanged()1100 public void callsWifiServiceCallbackOnSoftApConnectedClientsChanged() throws Exception { 1101 final Map<String, List<WifiClient>> testClients = new HashMap(); 1102 final Map<String, SoftApInfo> testInfos = new HashMap(); 1103 enterSoftApActiveMode(); 1104 mSoftApManagerCallback.onConnectedClientsOrInfoChanged(testInfos, testClients, false); 1105 mLooper.dispatchAll(); 1106 1107 verify(mSoftApStateMachineCallback).onConnectedClientsOrInfoChanged( 1108 testInfos, testClients, false); 1109 } 1110 1111 /** 1112 * Verifies that ClientsDisconnected event is being passed from SoftApManager 1113 * to WifiServiceImpl. 1114 */ 1115 @Test callsWifiServiceCallbackOnSoftApClientsDisconnected()1116 public void callsWifiServiceCallbackOnSoftApClientsDisconnected() throws Exception { 1117 List<WifiClient> testClients = new ArrayList<>(); 1118 enterSoftApActiveMode(); 1119 mSoftApManagerCallback.onClientsDisconnected(mTestSoftApInfo, testClients); 1120 mLooper.dispatchAll(); 1121 1122 verify(mSoftApStateMachineCallback).onClientsDisconnected( 1123 mTestSoftApInfo, testClients); 1124 } 1125 1126 /** 1127 * Test that we remain in the active state when we get a state change update that scan mode is 1128 * active. 1129 */ 1130 @Test testScanOnlyModeStaysActiveOnEnabledUpdate()1131 public void testScanOnlyModeStaysActiveOnEnabledUpdate() throws Exception { 1132 enterScanOnlyModeActiveState(); 1133 // now inject success through the Listener 1134 mClientListener.onStarted(mClientModeManager); 1135 mLooper.dispatchAll(); 1136 assertInEnabledState(); 1137 verify(mClientModeManager, never()).stop(); 1138 } 1139 1140 /** 1141 * Test that a config passed in to the call to enterSoftApMode is used to create the new 1142 * SoftApManager. 1143 */ 1144 @Test testConfigIsPassedToWifiInjector()1145 public void testConfigIsPassedToWifiInjector() throws Exception { 1146 Builder configBuilder = new SoftApConfiguration.Builder(); 1147 configBuilder.setSsid("ThisIsAConfig"); 1148 SoftApModeConfiguration softApConfig = new SoftApModeConfiguration( 1149 WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), mSoftApCapability, 1150 TEST_COUNTRYCODE, null); 1151 enterSoftApActiveMode(softApConfig); 1152 } 1153 1154 /** 1155 * Test that when enterSoftAPMode is called with a null config, we pass a null config to 1156 * WifiInjector.makeSoftApManager. 1157 * 1158 * Passing a null config to SoftApManager indicates that the default config should be used. 1159 */ 1160 @Test testNullConfigIsPassedToWifiInjector()1161 public void testNullConfigIsPassedToWifiInjector() throws Exception { 1162 enterSoftApActiveMode(); 1163 } 1164 1165 /** 1166 * Test that two calls to switch to SoftAPMode in succession ends up with the correct config. 1167 * 1168 * Expectation: we should end up in SoftAPMode state configured with the second config. 1169 */ 1170 @Test testStartSoftApModeTwiceWithTwoConfigs()1171 public void testStartSoftApModeTwiceWithTwoConfigs() throws Exception { 1172 when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore); 1173 Builder configBuilder1 = new SoftApConfiguration.Builder(); 1174 configBuilder1.setSsid("ThisIsAConfig"); 1175 SoftApModeConfiguration softApConfig1 = new SoftApModeConfiguration( 1176 WifiManager.IFACE_IP_MODE_TETHERED, configBuilder1.build(), 1177 mSoftApCapability, TEST_COUNTRYCODE, null); 1178 Builder configBuilder2 = new SoftApConfiguration.Builder(); 1179 configBuilder2.setSsid("ThisIsASecondConfig"); 1180 SoftApModeConfiguration softApConfig2 = new SoftApModeConfiguration( 1181 WifiManager.IFACE_IP_MODE_TETHERED, configBuilder2.build(), 1182 mSoftApCapability, TEST_COUNTRYCODE, null); 1183 1184 doAnswer(new Answer<SoftApManager>() { 1185 public SoftApManager answer(InvocationOnMock invocation) { 1186 Object[] args = invocation.getArguments(); 1187 mSoftApListener = (Listener<SoftApManager>) args[0]; 1188 return mSoftApManager; 1189 } 1190 }).when(mWifiInjector).makeSoftApManager(any(Listener.class), 1191 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(softApConfig1), any(), any(), 1192 anyBoolean()); 1193 // make a second softap manager 1194 SoftApManager softapManager = mock(SoftApManager.class); 1195 Mutable<Listener<SoftApManager>> softApListener = 1196 new Mutable<>(); 1197 doAnswer(new Answer<SoftApManager>() { 1198 public SoftApManager answer(InvocationOnMock invocation) { 1199 Object[] args = invocation.getArguments(); 1200 softApListener.value = (Listener<SoftApManager>) args[0]; 1201 return softapManager; 1202 } 1203 }).when(mWifiInjector).makeSoftApManager(any(Listener.class), 1204 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(softApConfig2), any(), any(), 1205 anyBoolean()); 1206 1207 mActiveModeWarden.startSoftAp(softApConfig1, TEST_WORKSOURCE); 1208 mLooper.dispatchAll(); 1209 mSoftApListener.onStarted(mSoftApManager); 1210 mActiveModeWarden.startSoftAp(softApConfig2, TEST_WORKSOURCE); 1211 mLooper.dispatchAll(); 1212 softApListener.value.onStarted(softapManager); 1213 1214 verify(mWifiInjector, times(2)).makeSoftApManager( 1215 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 1216 verify(mBatteryStats).reportWifiOn(); 1217 } 1218 1219 /** 1220 * Test that we safely disable wifi if it is already disabled. 1221 */ 1222 @Test disableWifiWhenAlreadyOff()1223 public void disableWifiWhenAlreadyOff() throws Exception { 1224 enterStaDisabledMode(false); 1225 verify(mWifiNative).getSupportedFeatureSet(null); 1226 verify(mWifiNative).isStaApConcurrencySupported(); 1227 verify(mWifiNative).isStaStaConcurrencySupported(); 1228 verify(mWifiNative).isP2pStaConcurrencySupported(); 1229 verify(mWifiNative).isNanStaConcurrencySupported(); 1230 verifyZeroInteractions(mWifiNative); 1231 } 1232 1233 /** 1234 * Trigger recovery and a bug report if we see a native failure 1235 * while the device is not shutting down 1236 */ 1237 @Test handleWifiNativeFailureDeviceNotShuttingDown()1238 public void handleWifiNativeFailureDeviceNotShuttingDown() throws Exception { 1239 mWifiNativeStatusListener.onStatusChanged(false); 1240 mLooper.dispatchAll(); 1241 verify(mWifiDiagnostics).triggerBugReportDataCapture( 1242 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE); 1243 verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE)); 1244 verify(mWifiConfigManager).writeDataToStorage(); 1245 } 1246 1247 /** 1248 * Verify the device shutting down doesn't trigger recovery or bug report. 1249 */ 1250 @Test handleWifiNativeFailureDeviceShuttingDown()1251 public void handleWifiNativeFailureDeviceShuttingDown() throws Exception { 1252 mActiveModeWarden.notifyShuttingDown(); 1253 mWifiNativeStatusListener.onStatusChanged(false); 1254 mLooper.dispatchAll(); 1255 verify(mWifiDiagnostics, never()).triggerBugReportDataCapture( 1256 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE); 1257 verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE)); 1258 verify(mWifiConfigManager, never()).writeDataToStorage(); 1259 } 1260 1261 /** 1262 * Verify an onStatusChanged callback with "true" does not trigger recovery. 1263 */ 1264 @Test handleWifiNativeStatusReady()1265 public void handleWifiNativeStatusReady() throws Exception { 1266 mWifiNativeStatusListener.onStatusChanged(true); 1267 mLooper.dispatchAll(); 1268 verify(mWifiDiagnostics, never()).triggerBugReportDataCapture( 1269 WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE); 1270 verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE)); 1271 verify(mWifiConfigManager, never()).writeDataToStorage(); 1272 } 1273 1274 /** 1275 * Verify that mode stop is safe even if the underlying Client mode exited already. 1276 */ 1277 @Test shutdownWifiDoesNotCrashWhenClientModeExitsOnDestroyed()1278 public void shutdownWifiDoesNotCrashWhenClientModeExitsOnDestroyed() throws Exception { 1279 enterClientModeActiveState(); 1280 1281 mClientListener.onStopped(mClientModeManager); 1282 mLooper.dispatchAll(); 1283 1284 shutdownWifi(); 1285 1286 assertInDisabledState(); 1287 } 1288 1289 /** 1290 * Verify that an interface destruction callback is safe after already having been stopped. 1291 */ 1292 @Test onDestroyedCallbackDoesNotCrashWhenClientModeAlreadyStopped()1293 public void onDestroyedCallbackDoesNotCrashWhenClientModeAlreadyStopped() throws Exception { 1294 enterClientModeActiveState(); 1295 1296 shutdownWifi(); 1297 1298 mClientListener.onStopped(mClientModeManager); 1299 mLooper.dispatchAll(); 1300 1301 assertInDisabledState(); 1302 } 1303 1304 /** 1305 * Verify that mode stop is safe even if the underlying softap mode exited already. 1306 */ 1307 @Test shutdownWifiDoesNotCrashWhenSoftApExitsOnDestroyed()1308 public void shutdownWifiDoesNotCrashWhenSoftApExitsOnDestroyed() throws Exception { 1309 enterSoftApActiveMode(); 1310 1311 mSoftApListener.onStopped(mSoftApManager); 1312 mLooper.dispatchAll(); 1313 SoftApState softApState = new SoftApState( 1314 WifiManager.WIFI_AP_STATE_DISABLED, 0, null, null); 1315 mSoftApManagerCallback.onStateChanged(softApState); 1316 mLooper.dispatchAll(); 1317 1318 shutdownWifi(); 1319 1320 verify(mSoftApStateMachineCallback).onStateChanged(softApState); 1321 } 1322 1323 /** 1324 * Verify that an interface destruction callback is safe after already having been stopped. 1325 */ 1326 @Test onDestroyedCallbackDoesNotCrashWhenSoftApModeAlreadyStopped()1327 public void onDestroyedCallbackDoesNotCrashWhenSoftApModeAlreadyStopped() throws Exception { 1328 enterSoftApActiveMode(); 1329 1330 shutdownWifi(); 1331 1332 mSoftApListener.onStopped(mSoftApManager); 1333 SoftApState softApState = new SoftApState( 1334 WifiManager.WIFI_AP_STATE_DISABLED, 0, null, null); 1335 mSoftApManagerCallback.onStateChanged(softApState); 1336 mLooper.dispatchAll(); 1337 1338 verify(mSoftApStateMachineCallback).onStateChanged(softApState); 1339 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 1340 } 1341 1342 /** 1343 * Verify that we do not crash when calling dump and wifi is fully disabled. 1344 */ 1345 @Test dumpWhenWifiFullyOffDoesNotCrash()1346 public void dumpWhenWifiFullyOffDoesNotCrash() throws Exception { 1347 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 1348 PrintWriter writer = new PrintWriter(stream); 1349 mActiveModeWarden.dump(null, writer, null); 1350 } 1351 1352 /** 1353 * Verify that we trigger dump on active mode managers. 1354 */ 1355 @Test dumpCallsActiveModeManagers()1356 public void dumpCallsActiveModeManagers() throws Exception { 1357 enterSoftApActiveMode(); 1358 enterClientModeActiveState(); 1359 1360 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 1361 PrintWriter writer = new PrintWriter(stream); 1362 mActiveModeWarden.dump(null, writer, null); 1363 1364 verify(mSoftApManager).dump(null, writer, null); 1365 verify(mClientModeManager).dump(null, writer, null); 1366 } 1367 1368 /** 1369 * Verify that stopping tethering doesn't stop LOHS. 1370 */ 1371 @Test testStopTetheringButNotLOHS()1372 public void testStopTetheringButNotLOHS() throws Exception { 1373 // prepare WiFi configurations 1374 when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore); 1375 SoftApModeConfiguration tetherConfig = 1376 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 1377 mSoftApCapability, TEST_COUNTRYCODE, null); 1378 SoftApConfiguration lohsConfigWC = mWifiApConfigStore.generateLocalOnlyHotspotConfig( 1379 mContext, null, mSoftApCapability); 1380 SoftApModeConfiguration lohsConfig = 1381 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_LOCAL_ONLY, lohsConfigWC, 1382 mSoftApCapability, TEST_COUNTRYCODE, null); 1383 1384 // mock SoftAPManagers 1385 when(mSoftApManager.getRole()).thenReturn(ROLE_SOFTAP_TETHERED); 1386 doAnswer(new Answer<SoftApManager>() { 1387 public SoftApManager answer(InvocationOnMock invocation) { 1388 Object[] args = invocation.getArguments(); 1389 mSoftApListener = (Listener<SoftApManager>) args[0]; 1390 return mSoftApManager; 1391 } 1392 }).when(mWifiInjector).makeSoftApManager(any(Listener.class), 1393 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(tetherConfig), 1394 eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 1395 // make a second softap manager 1396 SoftApManager lohsSoftapManager = mock(SoftApManager.class); 1397 when(lohsSoftapManager.getRole()).thenReturn(ROLE_SOFTAP_LOCAL_ONLY); 1398 Mutable<Listener<SoftApManager>> lohsSoftApListener = new Mutable<>(); 1399 doAnswer(new Answer<SoftApManager>() { 1400 public SoftApManager answer(InvocationOnMock invocation) { 1401 Object[] args = invocation.getArguments(); 1402 lohsSoftApListener.value = (Listener<SoftApManager>) args[0]; 1403 return lohsSoftapManager; 1404 } 1405 }).when(mWifiInjector).makeSoftApManager(any(Listener.class), 1406 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(lohsConfig), 1407 eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_LOCAL_ONLY), anyBoolean()); 1408 1409 // enable tethering and LOHS 1410 mActiveModeWarden.startSoftAp(tetherConfig, TEST_WORKSOURCE); 1411 mLooper.dispatchAll(); 1412 mSoftApListener.onStarted(mSoftApManager); 1413 mActiveModeWarden.startSoftAp(lohsConfig, TEST_WORKSOURCE); 1414 mLooper.dispatchAll(); 1415 lohsSoftApListener.value.onStarted(lohsSoftapManager); 1416 verify(mWifiInjector).makeSoftApManager(any(Listener.class), 1417 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(tetherConfig), 1418 eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 1419 verify(mWifiInjector).makeSoftApManager(any(Listener.class), 1420 any(WifiServiceImpl.SoftApCallbackInternal.class), eq(lohsConfig), 1421 eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_LOCAL_ONLY), anyBoolean()); 1422 verify(mBatteryStats).reportWifiOn(); 1423 1424 // disable tethering 1425 mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED); 1426 mLooper.dispatchAll(); 1427 verify(mSoftApManager).stop(); 1428 verify(lohsSoftapManager, never()).stop(); 1429 1430 mSoftApListener.onStopped(mSoftApManager); 1431 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 1432 } 1433 1434 /** 1435 * Verify that toggling wifi from disabled starts client mode. 1436 */ 1437 @Test enableWifi()1438 public void enableWifi() throws Exception { 1439 assertInDisabledState(); 1440 1441 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 1442 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 1443 mLooper.dispatchAll(); 1444 1445 verify(mWifiInjector).makeClientModeManager( 1446 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), 1447 anyBoolean()); 1448 mClientListener.onStarted(mClientModeManager); 1449 mLooper.dispatchAll(); 1450 1451 // always set primary, even with single STA 1452 verify(mWifiNative).setMultiStaPrimaryConnection(WIFI_IFACE_NAME); 1453 1454 assertInEnabledState(); 1455 } 1456 1457 /** 1458 * Test verifying that we can enter scan mode when the scan mode changes 1459 */ 1460 @Test enableScanMode()1461 public void enableScanMode() throws Exception { 1462 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1463 mActiveModeWarden.scanAlwaysModeChanged(); 1464 mLooper.dispatchAll(); 1465 verify(mWifiInjector).makeClientModeManager( 1466 any(), eq(new WorkSource(Process.WIFI_UID)), eq(ROLE_CLIENT_SCAN_ONLY), 1467 anyBoolean()); 1468 assertInEnabledState(); 1469 verify(mClientModeManager, never()).stop(); 1470 } 1471 1472 /** 1473 * Test verifying that we ignore scan enable event when wifi is already enabled. 1474 */ 1475 @Test ignoreEnableScanModeWhenWifiEnabled()1476 public void ignoreEnableScanModeWhenWifiEnabled() throws Exception { 1477 // Turn on WIFI 1478 assertInDisabledState(); 1479 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 1480 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 1481 mLooper.dispatchAll(); 1482 mClientListener.onStarted(mClientModeManager); 1483 mLooper.dispatchAll(); 1484 assertInEnabledState(); 1485 1486 // Now toggle scan only change, should be ignored. We should send a role change 1487 // again with PRIMARY & the cached requestorWs. 1488 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1489 mActiveModeWarden.scanAlwaysModeChanged(); 1490 mLooper.dispatchAll(); 1491 verify(mClientModeManager).setRole(ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); 1492 assertInEnabledState(); 1493 verify(mClientModeManager, never()).stop(); 1494 } 1495 1496 /** 1497 * Verify that if scanning is enabled at startup, we enter scan mode 1498 */ 1499 @Test testEnterScanModeAtStartWhenSet()1500 public void testEnterScanModeAtStartWhenSet() throws Exception { 1501 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1502 1503 mActiveModeWarden = createActiveModeWarden(); 1504 mActiveModeWarden.start(); 1505 mLooper.dispatchAll(); 1506 1507 assertInEnabledState(); 1508 } 1509 1510 /** 1511 * Verify that if Wifi is enabled at startup, we enter client mode 1512 */ 1513 @Test testEnterClientModeAtStartWhenSet()1514 public void testEnterClientModeAtStartWhenSet() throws Exception { 1515 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 1516 1517 mActiveModeWarden = createActiveModeWarden(); 1518 mActiveModeWarden.start(); 1519 mLooper.dispatchAll(); 1520 1521 verify(mWifiMetrics).noteWifiEnabledDuringBoot(true); 1522 1523 assertInEnabledState(); 1524 1525 verify(mWifiInjector) 1526 .makeClientModeManager(any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 1527 } 1528 1529 /** 1530 * Do not enter scan mode if location mode disabled. 1531 */ 1532 @Test testDoesNotEnterScanModeWhenLocationModeDisabled()1533 public void testDoesNotEnterScanModeWhenLocationModeDisabled() throws Exception { 1534 // Start a new WifiController with wifi disabled 1535 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1536 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 1537 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 1538 1539 mActiveModeWarden = createActiveModeWarden(); 1540 mActiveModeWarden.start(); 1541 mLooper.dispatchAll(); 1542 1543 assertInDisabledState(); 1544 1545 // toggling scan always available is not sufficient for scan mode 1546 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1547 mActiveModeWarden.scanAlwaysModeChanged(); 1548 mLooper.dispatchAll(); 1549 1550 assertInDisabledState(); 1551 } 1552 1553 /** 1554 * Only enter scan mode if location mode enabled 1555 */ 1556 @Test testEnterScanModeWhenLocationModeEnabled()1557 public void testEnterScanModeWhenLocationModeEnabled() throws Exception { 1558 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1559 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 1560 1561 reset(mContext); 1562 when(mContext.getResourceCache()).thenReturn(mWifiResourceCache); 1563 mActiveModeWarden = createActiveModeWarden(); 1564 mActiveModeWarden.start(); 1565 mLooper.dispatchAll(); 1566 1567 ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = 1568 ArgumentCaptor.forClass(BroadcastReceiver.class); 1569 // Note: Ignore lint warning UnspecifiedRegisterReceiverFlag since here is using 1570 // to test receiving for system broadcasts. The lint warning is a false alarm since 1571 // here is using argThat and hasAction. 1572 verify(mContext).registerReceiverForAllUsers( 1573 bcastRxCaptor.capture(), 1574 argThat(filter -> filter.hasAction(LocationManager.MODE_CHANGED_ACTION)), 1575 eq(null), any(Handler.class)); 1576 BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); 1577 1578 assertInDisabledState(); 1579 1580 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 1581 Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); 1582 broadcastReceiver.onReceive(mContext, intent); 1583 mLooper.dispatchAll(); 1584 1585 assertInEnabledState(); 1586 } 1587 1588 /** 1589 * Do not change Wi-Fi state when airplane mode changes if 1590 * DISALLOW_CHANGE_WIFI_STATE user restriction is set. 1591 */ 1592 @Test testWifiStateUnaffectedByAirplaneMode()1593 public void testWifiStateUnaffectedByAirplaneMode() throws Exception { 1594 assumeTrue(SdkLevel.isAtLeastT()); 1595 when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE), 1596 any())).thenReturn(true); 1597 when(mSettingsStore.updateAirplaneModeTracker()).thenReturn(true); 1598 1599 reset(mContext); 1600 when(mContext.getResourceCache()).thenReturn(mWifiResourceCache); 1601 mActiveModeWarden = createActiveModeWarden(); 1602 mActiveModeWarden.start(); 1603 mLooper.dispatchAll(); 1604 1605 ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = 1606 ArgumentCaptor.forClass(BroadcastReceiver.class); 1607 verify(mContext).registerReceiver( 1608 bcastRxCaptor.capture(), 1609 argThat(filter -> filter.hasAction(Intent.ACTION_AIRPLANE_MODE_CHANGED))); 1610 BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); 1611 1612 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1613 broadcastReceiver.onReceive(mContext, intent); 1614 mLooper.dispatchAll(); 1615 1616 verify(mSettingsStore, never()).handleAirplaneModeToggled(); 1617 1618 when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE), 1619 any())).thenReturn(false); 1620 broadcastReceiver.onReceive(mContext, intent); 1621 mLooper.dispatchAll(); 1622 1623 verify(mSettingsStore).handleAirplaneModeToggled(); 1624 verify(mLastCallerInfoManager, never()).put(eq(WifiManager.API_WIFI_ENABLED), 1625 anyInt(), anyInt(), anyInt(), any(), anyBoolean()); 1626 } 1627 1628 /** 1629 * Wi-Fi remains on when airplane mode changes if airplane mode enhancement is enabled. 1630 */ 1631 @Test testWifiRemainsOnAirplaneModeEnhancement()1632 public void testWifiRemainsOnAirplaneModeEnhancement() throws Exception { 1633 enterClientModeActiveState(); 1634 assertInEnabledState(); 1635 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 1636 1637 // Wi-Fi remains on when APM enhancement enabled 1638 assertWifiShutDown(() -> { 1639 when(mSettingsStore.shouldWifiRemainEnabledWhenApmEnabled()).thenReturn(true); 1640 mActiveModeWarden.airplaneModeToggled(); 1641 mLooper.dispatchAll(); 1642 }, 0); 1643 verify(mLastCallerInfoManager, never()).put(eq(WifiManager.API_WIFI_ENABLED), 1644 anyInt(), anyInt(), anyInt(), any(), anyBoolean()); 1645 1646 // Wi-Fi shuts down when APM enhancement disabled 1647 assertWifiShutDown(() -> { 1648 when(mSettingsStore.shouldWifiRemainEnabledWhenApmEnabled()).thenReturn(false); 1649 mActiveModeWarden.airplaneModeToggled(); 1650 mLooper.dispatchAll(); 1651 }); 1652 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), anyInt(), 1653 anyInt(), eq("android_apm"), eq(false)); 1654 } 1655 1656 /** Wi-Fi state is restored properly when SoftAp is enabled during airplane mode. */ 1657 @Test testWifiStateRestoredWhenSoftApEnabledDuringApm()1658 public void testWifiStateRestoredWhenSoftApEnabledDuringApm() throws Exception { 1659 enableWifi(); 1660 assertInEnabledState(); 1661 1662 // enabling airplane mode shuts down wifi 1663 assertWifiShutDown( 1664 () -> { 1665 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 1666 mActiveModeWarden.airplaneModeToggled(); 1667 mLooper.dispatchAll(); 1668 }); 1669 verify(mLastCallerInfoManager) 1670 .put( 1671 eq(WifiManager.API_WIFI_ENABLED), 1672 anyInt(), 1673 anyInt(), 1674 anyInt(), 1675 eq("android_apm"), 1676 eq(false)); 1677 mClientListener.onStopped(mClientModeManager); 1678 mLooper.dispatchAll(); 1679 1680 // start SoftAp 1681 mActiveModeWarden.startSoftAp( 1682 new SoftApModeConfiguration( 1683 WifiManager.IFACE_IP_MODE_LOCAL_ONLY, 1684 null, 1685 mSoftApCapability, 1686 TEST_COUNTRYCODE, 1687 null), 1688 TEST_WORKSOURCE); 1689 mLooper.dispatchAll(); 1690 1691 // disabling airplane mode enables wifi 1692 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 1693 mActiveModeWarden.airplaneModeToggled(); 1694 mLooper.dispatchAll(); 1695 verify(mLastCallerInfoManager) 1696 .put( 1697 eq(WifiManager.API_WIFI_ENABLED), 1698 anyInt(), 1699 anyInt(), 1700 anyInt(), 1701 eq("android_apm"), 1702 eq(true)); 1703 } 1704 1705 /** 1706 * Disabling location mode when in scan mode will disable wifi 1707 */ 1708 @Test testExitScanModeWhenLocationModeDisabled()1709 public void testExitScanModeWhenLocationModeDisabled() throws Exception { 1710 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1711 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 1712 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 1713 1714 reset(mContext); 1715 when(mContext.getResourceCache()).thenReturn(mWifiResourceCache); 1716 mActiveModeWarden = createActiveModeWarden(); 1717 mActiveModeWarden.start(); 1718 mLooper.dispatchAll(); 1719 mClientListener.onStarted(mClientModeManager); 1720 mLooper.dispatchAll(); 1721 1722 ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = 1723 ArgumentCaptor.forClass(BroadcastReceiver.class); 1724 verify(mContext).registerReceiverForAllUsers( 1725 bcastRxCaptor.capture(), 1726 argThat(filter -> filter.hasAction(LocationManager.MODE_CHANGED_ACTION)), 1727 eq(null), any(Handler.class)); 1728 BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); 1729 1730 assertInEnabledState(); 1731 1732 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 1733 Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); 1734 broadcastReceiver.onReceive(mContext, intent); 1735 mLooper.dispatchAll(); 1736 1737 mClientListener.onStopped(mClientModeManager); 1738 mLooper.dispatchAll(); 1739 1740 assertInDisabledState(); 1741 } 1742 1743 /** 1744 * When in Client mode, make sure ECM triggers wifi shutdown. 1745 */ 1746 @Test testEcmOnFromClientMode()1747 public void testEcmOnFromClientMode() throws Exception { 1748 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 1749 enableWifi(); 1750 1751 // Test with WifiDisableInECBM turned on: 1752 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1753 1754 assertWifiShutDown(() -> { 1755 // test ecm changed 1756 emergencyCallbackModeChanged(true); 1757 mLooper.dispatchAll(); 1758 }); 1759 } 1760 1761 /** 1762 * ECM disabling messages, when in client mode (not expected) do not trigger state changes. 1763 */ 1764 @Test testEcmOffInClientMode()1765 public void testEcmOffInClientMode() throws Exception { 1766 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 1767 enableWifi(); 1768 1769 // Test with WifiDisableInECBM turned off 1770 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 1771 1772 assertEnteredEcmMode(() -> { 1773 // test ecm changed 1774 emergencyCallbackModeChanged(true); 1775 mLooper.dispatchAll(); 1776 }); 1777 } 1778 1779 /** 1780 * When ECM activates and we are in client mode, disabling ECM should return us to client mode. 1781 */ 1782 @Test testEcmDisabledReturnsToClientMode()1783 public void testEcmDisabledReturnsToClientMode() throws Exception { 1784 enableWifi(); 1785 assertInEnabledState(); 1786 1787 // Test with WifiDisableInECBM turned on: 1788 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1789 1790 assertWifiShutDown(() -> { 1791 // test ecm changed 1792 emergencyCallbackModeChanged(true); 1793 mLooper.dispatchAll(); 1794 }); 1795 1796 // test ecm changed 1797 emergencyCallbackModeChanged(false); 1798 mLooper.dispatchAll(); 1799 1800 assertInEnabledState(); 1801 } 1802 1803 /** 1804 * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed 1805 * update. 1806 */ 1807 @Test testEcmOnFromScanMode()1808 public void testEcmOnFromScanMode() throws Exception { 1809 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1810 mActiveModeWarden.scanAlwaysModeChanged(); 1811 mLooper.dispatchAll(); 1812 1813 mClientListener.onStarted(mClientModeManager); 1814 mLooper.dispatchAll(); 1815 1816 assertInEnabledState(); 1817 1818 // Test with WifiDisableInECBM turned on: 1819 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1820 1821 assertWifiShutDown(() -> { 1822 // test ecm changed 1823 emergencyCallbackModeChanged(true); 1824 mLooper.dispatchAll(); 1825 }); 1826 } 1827 1828 /** 1829 * When Ecm mode is disabled, we should not shut down scan mode if we get an emergency mode 1830 * changed update, but we should turn off soft AP 1831 */ 1832 @Test testEcmOffInScanMode()1833 public void testEcmOffInScanMode() throws Exception { 1834 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1835 mActiveModeWarden.scanAlwaysModeChanged(); 1836 mLooper.dispatchAll(); 1837 1838 assertInEnabledState(); 1839 1840 // Test with WifiDisableInECBM turned off: 1841 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 1842 1843 assertEnteredEcmMode(() -> { 1844 // test ecm changed 1845 emergencyCallbackModeChanged(true); 1846 mLooper.dispatchAll(); 1847 }); 1848 } 1849 1850 /** 1851 * When ECM is disabled, we should return to scan mode 1852 */ 1853 @Test testEcmDisabledReturnsToScanMode()1854 public void testEcmDisabledReturnsToScanMode() throws Exception { 1855 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 1856 mActiveModeWarden.scanAlwaysModeChanged(); 1857 mLooper.dispatchAll(); 1858 1859 assertInEnabledState(); 1860 1861 // Test with WifiDisableInECBM turned on: 1862 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1863 1864 assertWifiShutDown(() -> { 1865 // test ecm changed 1866 emergencyCallbackModeChanged(true); 1867 mLooper.dispatchAll(); 1868 }); 1869 1870 // test ecm changed 1871 emergencyCallbackModeChanged(false); 1872 mLooper.dispatchAll(); 1873 1874 assertInEnabledState(); 1875 } 1876 1877 /** 1878 * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed 1879 * update. 1880 */ 1881 @Test testEcmOnFromSoftApMode()1882 public void testEcmOnFromSoftApMode() throws Exception { 1883 enterSoftApActiveMode(); 1884 1885 // Test with WifiDisableInECBM turned on: 1886 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1887 1888 assertEnteredEcmMode(() -> { 1889 // test ecm changed 1890 emergencyCallbackModeChanged(true); 1891 mLooper.dispatchAll(); 1892 }); 1893 } 1894 1895 /** 1896 * When Ecm mode is disabled, we should shut down softap mode if we get an emergency mode 1897 * changed update 1898 */ 1899 @Test testEcmOffInSoftApMode()1900 public void testEcmOffInSoftApMode() throws Exception { 1901 enterSoftApActiveMode(); 1902 1903 // Test with WifiDisableInECBM turned off: 1904 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 1905 1906 // test ecm changed 1907 emergencyCallbackModeChanged(true); 1908 mLooper.dispatchAll(); 1909 1910 verify(mSoftApManager).stop(); 1911 } 1912 1913 /** 1914 * When ECM is activated and we were in softap mode, we should just return to wifi off when ECM 1915 * ends 1916 */ 1917 @Test testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn()1918 public void testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn() throws Exception { 1919 assertInDisabledState(); 1920 1921 enterSoftApActiveMode(); 1922 1923 // verify Soft AP Manager started 1924 verify(mWifiInjector).makeSoftApManager( 1925 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 1926 1927 // Test with WifiDisableInECBM turned on: 1928 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1929 1930 assertEnteredEcmMode(() -> { 1931 // test ecm changed 1932 emergencyCallbackModeChanged(true); 1933 mLooper.dispatchAll(); 1934 mSoftApListener.onStopped(mSoftApManager); 1935 mLooper.dispatchAll(); 1936 }); 1937 1938 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 1939 1940 // test ecm changed 1941 emergencyCallbackModeChanged(false); 1942 mLooper.dispatchAll(); 1943 1944 assertInDisabledState(); 1945 1946 // verify no additional calls to enable softap 1947 verify(mWifiInjector).makeSoftApManager( 1948 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 1949 } 1950 1951 /** 1952 * Wifi should remain off when already disabled and we enter ECM. 1953 */ 1954 @Test testEcmOnFromDisabledMode()1955 public void testEcmOnFromDisabledMode() throws Exception { 1956 assertInDisabledState(); 1957 verify(mWifiInjector, never()).makeSoftApManager( 1958 any(), any(), any(), any(), any(), anyBoolean()); 1959 verify(mWifiInjector, never()).makeClientModeManager( 1960 any(), any(), any(), anyBoolean()); 1961 1962 // Test with WifiDisableInECBM turned on: 1963 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1964 1965 assertEnteredEcmMode(() -> { 1966 // test ecm changed 1967 emergencyCallbackModeChanged(true); 1968 mLooper.dispatchAll(); 1969 }); 1970 } 1971 1972 1973 /** 1974 * Updates about call state change also trigger entry of ECM mode. 1975 */ 1976 @Test testEnterEcmOnEmergencyCallStateChange()1977 public void testEnterEcmOnEmergencyCallStateChange() throws Exception { 1978 assertInDisabledState(); 1979 1980 enableWifi(); 1981 assertInEnabledState(); 1982 1983 // Test with WifiDisableInECBM turned on: 1984 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 1985 1986 assertEnteredEcmMode(() -> { 1987 // test call state changed 1988 emergencyCallStateChanged(true); 1989 mLooper.dispatchAll(); 1990 mClientListener.onStopped(mClientModeManager); 1991 mLooper.dispatchAll(); 1992 }); 1993 1994 emergencyCallStateChanged(false); 1995 mLooper.dispatchAll(); 1996 1997 assertInEnabledState(); 1998 } 1999 2000 /** 2001 * Verify when both ECM and call state changes arrive, we enter ECM mode 2002 */ 2003 @Test testEnterEcmWithBothSignals()2004 public void testEnterEcmWithBothSignals() throws Exception { 2005 assertInDisabledState(); 2006 2007 enableWifi(); 2008 assertInEnabledState(); 2009 2010 // Test with WifiDisableInECBM turned on: 2011 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2012 2013 assertWifiShutDown(() -> { 2014 emergencyCallStateChanged(true); 2015 mLooper.dispatchAll(); 2016 mClientListener.onStopped(mClientModeManager); 2017 mLooper.dispatchAll(); 2018 }); 2019 2020 assertWifiShutDown(() -> { 2021 emergencyCallbackModeChanged(true); 2022 mLooper.dispatchAll(); 2023 }, 0); // does not cause another shutdown 2024 2025 // client mode only started once so far 2026 verify(mWifiInjector).makeClientModeManager( 2027 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2028 2029 emergencyCallStateChanged(false); 2030 mLooper.dispatchAll(); 2031 2032 // stay in ecm, do not send an additional client mode trigger 2033 assertInEmergencyMode(); 2034 // assert that the underlying state is in disabled state 2035 assertInDisabledState(); 2036 2037 // client mode still only started once 2038 verify(mWifiInjector).makeClientModeManager( 2039 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2040 2041 emergencyCallbackModeChanged(false); 2042 mLooper.dispatchAll(); 2043 2044 // now we can re-enable wifi 2045 verify(mWifiInjector, times(2)).makeClientModeManager( 2046 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2047 assertInEnabledState(); 2048 } 2049 2050 /** 2051 * Verify when both ECM and call state changes arrive but out of order, we enter ECM mode 2052 */ 2053 @Test testEnterEcmWithBothSignalsOutOfOrder()2054 public void testEnterEcmWithBothSignalsOutOfOrder() throws Exception { 2055 assertInDisabledState(); 2056 2057 enableWifi(); 2058 2059 assertInEnabledState(); 2060 verify(mWifiInjector).makeClientModeManager( 2061 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2062 2063 // Test with WifiDisableInECBM turned on: 2064 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2065 2066 assertEnteredEcmMode(() -> { 2067 emergencyCallbackModeChanged(true); 2068 mLooper.dispatchAll(); 2069 mClientListener.onStopped(mClientModeManager); 2070 mLooper.dispatchAll(); 2071 }); 2072 assertInDisabledState(); 2073 2074 assertEnteredEcmMode(() -> { 2075 emergencyCallStateChanged(true); 2076 mLooper.dispatchAll(); 2077 }, 0); // does not enter ECM state again 2078 2079 emergencyCallStateChanged(false); 2080 mLooper.dispatchAll(); 2081 2082 // stay in ecm, do not send an additional client mode trigger 2083 assertInEmergencyMode(); 2084 // assert that the underlying state is in disabled state 2085 assertInDisabledState(); 2086 2087 // client mode still only started once 2088 verify(mWifiInjector).makeClientModeManager( 2089 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2090 2091 emergencyCallbackModeChanged(false); 2092 mLooper.dispatchAll(); 2093 2094 // now we can re-enable wifi 2095 verify(mWifiInjector, times(2)).makeClientModeManager( 2096 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2097 assertInEnabledState(); 2098 } 2099 2100 /** 2101 * Verify when both ECM and call state changes arrive but completely out of order, 2102 * we still enter and properly exit ECM mode 2103 */ 2104 @Test testEnterEcmWithBothSignalsOppositeOrder()2105 public void testEnterEcmWithBothSignalsOppositeOrder() throws Exception { 2106 assertInDisabledState(); 2107 2108 enableWifi(); 2109 2110 assertInEnabledState(); 2111 verify(mWifiInjector).makeClientModeManager( 2112 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2113 2114 // Test with WifiDisableInECBM turned on: 2115 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2116 2117 assertEnteredEcmMode(() -> { 2118 emergencyCallStateChanged(true); 2119 mLooper.dispatchAll(); 2120 mClientListener.onStopped(mClientModeManager); 2121 mLooper.dispatchAll(); 2122 }); 2123 assertInDisabledState(); 2124 2125 assertEnteredEcmMode(() -> { 2126 emergencyCallbackModeChanged(true); 2127 mLooper.dispatchAll(); 2128 }, 0); // still only 1 shutdown 2129 2130 emergencyCallbackModeChanged(false); 2131 mLooper.dispatchAll(); 2132 2133 // stay in ecm, do not send an additional client mode trigger 2134 assertInEmergencyMode(); 2135 // assert that the underlying state is in disabled state 2136 assertInDisabledState(); 2137 2138 // client mode still only started once 2139 verify(mWifiInjector).makeClientModeManager( 2140 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2141 2142 emergencyCallStateChanged(false); 2143 mLooper.dispatchAll(); 2144 2145 // now we can re-enable wifi 2146 verify(mWifiInjector, times(2)).makeClientModeManager( 2147 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2148 assertInEnabledState(); 2149 } 2150 2151 /** 2152 * When ECM is active, we might get addition signals of ECM mode, drop those additional signals, 2153 * we must exit when one of each signal is received. 2154 * 2155 * In any case, duplicate signals indicate a bug from Telephony. Each signal should be turned 2156 * off before it is turned on again. 2157 */ 2158 @Test testProperExitFromEcmModeWithMultipleMessages()2159 public void testProperExitFromEcmModeWithMultipleMessages() throws Exception { 2160 assertInDisabledState(); 2161 2162 enableWifi(); 2163 2164 verify(mWifiInjector).makeClientModeManager( 2165 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2166 assertInEnabledState(); 2167 2168 // Test with WifiDisableInECBM turned on: 2169 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2170 2171 assertEnteredEcmMode(() -> { 2172 emergencyCallbackModeChanged(true); 2173 emergencyCallStateChanged(true); 2174 emergencyCallStateChanged(true); 2175 emergencyCallbackModeChanged(true); 2176 emergencyCallbackModeChanged(true); 2177 mLooper.dispatchAll(); 2178 mClientListener.onStopped(mClientModeManager); 2179 mLooper.dispatchAll(); 2180 }); 2181 assertInDisabledState(); 2182 2183 assertEnteredEcmMode(() -> { 2184 emergencyCallbackModeChanged(false); 2185 mLooper.dispatchAll(); 2186 emergencyCallbackModeChanged(false); 2187 mLooper.dispatchAll(); 2188 emergencyCallbackModeChanged(false); 2189 mLooper.dispatchAll(); 2190 emergencyCallbackModeChanged(false); 2191 mLooper.dispatchAll(); 2192 }, 0); 2193 2194 // didn't enter client mode again 2195 verify(mWifiInjector).makeClientModeManager( 2196 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2197 assertInDisabledState(); 2198 2199 // now we will exit ECM 2200 emergencyCallStateChanged(false); 2201 mLooper.dispatchAll(); 2202 2203 // now we can re-enable wifi 2204 verify(mWifiInjector, times(2)).makeClientModeManager( 2205 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2206 assertInEnabledState(); 2207 } 2208 2209 /** 2210 * Toggling wifi on when in ECM does not exit ecm mode and enable wifi 2211 */ 2212 @Test testWifiDoesNotToggleOnWhenInEcm()2213 public void testWifiDoesNotToggleOnWhenInEcm() throws Exception { 2214 assertInDisabledState(); 2215 2216 // Test with WifiDisableInECBM turned on: 2217 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2218 // test ecm changed 2219 assertEnteredEcmMode(() -> { 2220 emergencyCallbackModeChanged(true); 2221 mLooper.dispatchAll(); 2222 }); 2223 2224 // now toggle wifi and verify we do not start wifi 2225 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 2226 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 2227 mLooper.dispatchAll(); 2228 2229 verify(mWifiInjector, never()).makeClientModeManager( 2230 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2231 assertInDisabledState(); 2232 assertInEmergencyMode(); 2233 2234 // now we will exit ECM 2235 emergencyCallbackModeChanged(false); 2236 mLooper.dispatchAll(); 2237 assertNotInEmergencyMode(); 2238 2239 // Wifi toggle on now takes effect 2240 verify(mWifiInjector).makeClientModeManager( 2241 any(), eq(SETTINGS_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2242 assertInEnabledState(); 2243 } 2244 2245 /** 2246 * Toggling wifi off when in ECM does not disable wifi when getConfigWiFiDisableInECBM is 2247 * disabled. 2248 */ 2249 @Test testWifiDoesNotToggleOffWhenInEcmAndConfigDisabled()2250 public void testWifiDoesNotToggleOffWhenInEcmAndConfigDisabled() throws Exception { 2251 enableWifi(); 2252 assertInEnabledState(); 2253 verify(mWifiInjector).makeClientModeManager( 2254 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2255 2256 // Test with WifiDisableInECBM turned off 2257 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 2258 // test ecm changed 2259 assertEnteredEcmMode(() -> { 2260 emergencyCallbackModeChanged(true); 2261 mLooper.dispatchAll(); 2262 }); 2263 2264 // now toggle wifi and verify we do not start wifi 2265 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 2266 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 2267 mLooper.dispatchAll(); 2268 2269 // still only called once 2270 verify(mWifiInjector).makeClientModeManager( 2271 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2272 verify(mClientModeManager, never()).stop(); 2273 assertInEnabledState(); 2274 assertInEmergencyMode(); 2275 2276 // now we will exit ECM 2277 emergencyCallbackModeChanged(false); 2278 mLooper.dispatchAll(); 2279 assertNotInEmergencyMode(); 2280 2281 // Wifi toggle off now takes effect 2282 verify(mClientModeManager).stop(); 2283 mClientListener.onStopped(mClientModeManager); 2284 mLooper.dispatchAll(); 2285 assertInDisabledState(); 2286 } 2287 2288 @Test testAirplaneModeDoesNotToggleOnWhenInEcm()2289 public void testAirplaneModeDoesNotToggleOnWhenInEcm() throws Exception { 2290 // TODO(b/139829963): investigate the expected behavior is when toggling airplane mode in 2291 // ECM 2292 } 2293 2294 /** 2295 * Toggling scan mode when in ECM does not exit ecm mode and enable scan mode 2296 */ 2297 @Test testScanModeDoesNotToggleOnWhenInEcm()2298 public void testScanModeDoesNotToggleOnWhenInEcm() throws Exception { 2299 assertInDisabledState(); 2300 2301 // Test with WifiDisableInECBM turned on: 2302 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2303 assertEnteredEcmMode(() -> { 2304 // test ecm changed 2305 emergencyCallbackModeChanged(true); 2306 mLooper.dispatchAll(); 2307 }); 2308 2309 // now enable scanning and verify we do not start wifi 2310 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 2311 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 2312 mActiveModeWarden.scanAlwaysModeChanged(); 2313 mLooper.dispatchAll(); 2314 2315 verify(mWifiInjector, never()).makeClientModeManager( 2316 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2317 assertInDisabledState(); 2318 } 2319 2320 2321 /** 2322 * Toggling softap mode when in ECM does not exit ecm mode and enable softap 2323 */ 2324 @Test testSoftApModeDoesNotToggleOnWhenInEcm()2325 public void testSoftApModeDoesNotToggleOnWhenInEcm() throws Exception { 2326 assertInDisabledState(); 2327 2328 // Test with WifiDisableInECBM turned on: 2329 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2330 assertEnteredEcmMode(() -> { 2331 // test ecm changed 2332 emergencyCallbackModeChanged(true); 2333 mLooper.dispatchAll(); 2334 }); 2335 2336 // try to start Soft AP 2337 mActiveModeWarden.startSoftAp( 2338 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 2339 mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE); 2340 mLooper.dispatchAll(); 2341 2342 verify(mWifiInjector, never()) 2343 .makeSoftApManager(any(), any(), any(), eq(TEST_WORKSOURCE), any(), anyBoolean()); 2344 assertInDisabledState(); 2345 2346 // verify triggered Soft AP failure callback 2347 ArgumentCaptor<SoftApState> softApStateCaptor = 2348 ArgumentCaptor.forClass(SoftApState.class); 2349 verify(mSoftApStateMachineCallback).onStateChanged(softApStateCaptor.capture()); 2350 assertThat(softApStateCaptor.getValue().getState()).isEqualTo(WIFI_AP_STATE_FAILED); 2351 assertThat(softApStateCaptor.getValue().getFailureReason()) 2352 .isEqualTo(SAP_START_FAILURE_GENERAL); 2353 assertThat(softApStateCaptor.getValue().getFailureReasonInternal()) 2354 .isEqualTo(SAP_START_FAILURE_GENERAL); 2355 2356 // try to start LOHS 2357 mActiveModeWarden.startSoftAp( 2358 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null, 2359 mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE); 2360 mLooper.dispatchAll(); 2361 2362 verify(mWifiInjector, never()) 2363 .makeSoftApManager(any(), any(), any(), eq(TEST_WORKSOURCE), any(), anyBoolean()); 2364 assertInDisabledState(); 2365 2366 // verify triggered LOHS failure callback 2367 verify(mLohsStateMachineCallback).onStateChanged(softApStateCaptor.capture()); 2368 assertThat(softApStateCaptor.getValue().getState()).isEqualTo(WIFI_AP_STATE_FAILED); 2369 assertThat(softApStateCaptor.getValue().getFailureReason()) 2370 .isEqualTo(SAP_START_FAILURE_GENERAL); 2371 assertThat(softApStateCaptor.getValue().getFailureReasonInternal()) 2372 .isEqualTo(SAP_START_FAILURE_GENERAL); 2373 } 2374 2375 /** 2376 * Toggling off softap mode when in ECM does not induce a mode change 2377 */ 2378 @Test testSoftApStoppedDoesNotSwitchModesWhenInEcm()2379 public void testSoftApStoppedDoesNotSwitchModesWhenInEcm() throws Exception { 2380 assertInDisabledState(); 2381 2382 // Test with WifiDisableInECBM turned on: 2383 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2384 assertEnteredEcmMode(() -> { 2385 // test ecm changed 2386 emergencyCallbackModeChanged(true); 2387 mLooper.dispatchAll(); 2388 }); 2389 2390 mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2391 mLooper.dispatchAll(); 2392 2393 assertInDisabledState(); 2394 verifyNoMoreInteractions(mSoftApManager, mClientModeManager); 2395 } 2396 2397 /** 2398 * Toggling softap mode when in airplane mode needs to enable softap 2399 */ 2400 @Test testSoftApModeToggleWhenInAirplaneMode()2401 public void testSoftApModeToggleWhenInAirplaneMode() throws Exception { 2402 // Test with airplane mode turned on: 2403 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 2404 2405 // Turn on SoftAp. 2406 mActiveModeWarden.startSoftAp( 2407 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 2408 mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE); 2409 mLooper.dispatchAll(); 2410 verify(mWifiInjector) 2411 .makeSoftApManager(any(), any(), any(), eq(TEST_WORKSOURCE), any(), anyBoolean()); 2412 2413 // Turn off SoftAp. 2414 mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2415 mLooper.dispatchAll(); 2416 2417 verify(mSoftApManager).stop(); 2418 } 2419 2420 /** 2421 * Toggling off scan mode when in ECM does not induce a mode change 2422 */ 2423 @Test testScanModeStoppedSwitchModeToDisabledStateWhenInEcm()2424 public void testScanModeStoppedSwitchModeToDisabledStateWhenInEcm() throws Exception { 2425 enterScanOnlyModeActiveState(); 2426 assertInEnabledState(); 2427 2428 // Test with WifiDisableInECBM turned on: 2429 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2430 assertEnteredEcmMode(() -> { 2431 // test ecm changed 2432 emergencyCallbackModeChanged(true); 2433 mLooper.dispatchAll(); 2434 mClientListener.onStopped(mClientModeManager); 2435 mLooper.dispatchAll(); 2436 }); 2437 2438 // Spurious onStopped 2439 mClientListener.onStopped(mClientModeManager); 2440 mLooper.dispatchAll(); 2441 2442 assertInDisabledState(); 2443 } 2444 2445 /** 2446 * Toggling off client mode when in ECM does not induce a mode change 2447 */ 2448 @Test testClientModeStoppedSwitchModeToDisabledStateWhenInEcm()2449 public void testClientModeStoppedSwitchModeToDisabledStateWhenInEcm() throws Exception { 2450 enterClientModeActiveState(); 2451 assertInEnabledState(); 2452 2453 // Test with WifiDisableInECBM turned on: 2454 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2455 assertEnteredEcmMode(() -> { 2456 // test ecm changed 2457 emergencyCallbackModeChanged(true); 2458 mLooper.dispatchAll(); 2459 mClientListener.onStopped(mClientModeManager); 2460 mLooper.dispatchAll(); 2461 }); 2462 2463 // Spurious onStopped 2464 mClientListener.onStopped(mClientModeManager); 2465 mLooper.dispatchAll(); 2466 2467 assertInDisabledState(); 2468 } 2469 2470 /** 2471 * When AP mode is enabled and wifi was previously in AP mode, we should return to 2472 * EnabledState after the AP is disabled. 2473 * Enter EnabledState, activate AP mode, disable AP mode. 2474 * <p> 2475 * Expected: AP should successfully start and exit, then return to EnabledState. 2476 */ 2477 @Test testReturnToEnabledStateAfterAPModeShutdown()2478 public void testReturnToEnabledStateAfterAPModeShutdown() throws Exception { 2479 enableWifi(); 2480 assertInEnabledState(); 2481 verify(mWifiInjector).makeClientModeManager( 2482 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2483 2484 mActiveModeWarden.startSoftAp( 2485 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 2486 mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE); 2487 // add an "unexpected" sta mode stop to simulate a single interface device 2488 mClientListener.onStopped(mClientModeManager); 2489 mLooper.dispatchAll(); 2490 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2491 2492 // Now stop the AP 2493 mSoftApListener.onStopped(mSoftApManager); 2494 mLooper.dispatchAll(); 2495 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 2496 2497 // We should re-enable client mode 2498 verify(mWifiInjector, times(2)).makeClientModeManager( 2499 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2500 assertInEnabledState(); 2501 } 2502 2503 /** 2504 * When in STA mode and SoftAP is enabled and the device supports STA+AP (i.e. the STA wasn't 2505 * shut down when the AP started), both modes will be running concurrently. 2506 * 2507 * Then when the AP is disabled, we should remain in STA mode. 2508 * 2509 * Enter EnabledState, activate AP mode, toggle WiFi off. 2510 * <p> 2511 * Expected: AP should successfully start and exit, then return to EnabledState. 2512 */ 2513 @Test testReturnToEnabledStateAfterWifiEnabledShutdown()2514 public void testReturnToEnabledStateAfterWifiEnabledShutdown() throws Exception { 2515 enableWifi(); 2516 assertInEnabledState(); 2517 verify(mWifiInjector).makeClientModeManager( 2518 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2519 2520 mActiveModeWarden.startSoftAp( 2521 new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, 2522 mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE); 2523 mLooper.dispatchAll(); 2524 2525 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 2526 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 2527 mSoftApListener.onStopped(mSoftApManager); 2528 mLooper.dispatchAll(); 2529 2530 // wasn't called again 2531 verify(mWifiInjector).makeClientModeManager( 2532 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2533 assertInEnabledState(); 2534 } 2535 2536 @Test testRestartWifiStackInEnabledStateTriggersBugReport()2537 public void testRestartWifiStackInEnabledStateTriggersBugReport() throws Exception { 2538 enableWifi(); 2539 2540 // note: using a reason that will typical not start a bug report on purpose to guarantee 2541 // that it is the flag and not the reason which controls it. 2542 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG, 2543 true); 2544 mLooper.dispatchAll(); 2545 verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); 2546 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2547 } 2548 2549 @Test testRestartWifiWatchdogDoesNotTriggerBugReport()2550 public void testRestartWifiWatchdogDoesNotTriggerBugReport() throws Exception { 2551 enableWifi(); 2552 // note: using a reason that will typical start a bug report on purpose to guarantee that 2553 // it is the flag and not the reason which controls it. 2554 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2555 false); 2556 mLooper.dispatchAll(); 2557 verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString()); 2558 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2559 } 2560 2561 /** 2562 * When in sta mode, CMD_RECOVERY_DISABLE_WIFI messages should trigger wifi to disable. 2563 */ 2564 @Test testRecoveryDisabledTurnsWifiOff()2565 public void testRecoveryDisabledTurnsWifiOff() throws Exception { 2566 enableWifi(); 2567 assertInEnabledState(); 2568 mActiveModeWarden.recoveryDisableWifi(); 2569 mLooper.dispatchAll(); 2570 verify(mClientModeManager).stop(); 2571 mClientListener.onStopped(mClientModeManager); 2572 mLooper.dispatchAll(); 2573 assertInDisabledState(); 2574 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2575 } 2576 2577 /** 2578 * When wifi is disabled, CMD_RECOVERY_DISABLE_WIFI should not trigger a state change. 2579 */ 2580 @Test testRecoveryDisabledWhenWifiAlreadyOff()2581 public void testRecoveryDisabledWhenWifiAlreadyOff() throws Exception { 2582 assertInDisabledState(); 2583 assertWifiShutDown(() -> { 2584 mActiveModeWarden.recoveryDisableWifi(); 2585 mLooper.dispatchAll(); 2586 }); 2587 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS + 10); 2588 mLooper.dispatchAll(); 2589 2590 // Ensure we did not restart wifi. 2591 assertInDisabledState(); 2592 } 2593 2594 /** 2595 * The command to trigger a WiFi reset should not trigger any action by WifiController if we 2596 * are not in STA mode. 2597 * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures 2598 * should be ignored. 2599 * Create and start WifiController in DisabledState, send command to restart WiFi 2600 * <p> 2601 * Expected: WiFiController should not call ActiveModeWarden.disableWifi() 2602 */ 2603 @Test testRestartWifiStackInDisabledState()2604 public void testRestartWifiStackInDisabledState() throws Exception { 2605 assertInDisabledState(); 2606 2607 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2608 true); 2609 mLooper.dispatchAll(); 2610 2611 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS + 10); 2612 mLooper.dispatchAll(); 2613 2614 assertInDisabledState(); 2615 verifyNoMoreInteractions(mClientModeManager, mSoftApManager); 2616 } 2617 2618 @Test testNetworkStateChangeListener()2619 public void testNetworkStateChangeListener() throws Exception { 2620 IWifiNetworkStateChangedListener testListener = 2621 mock(IWifiNetworkStateChangedListener.class); 2622 when(testListener.asBinder()).thenReturn(mock(IBinder.class)); 2623 2624 // register listener and verify results delivered 2625 mActiveModeWarden.addWifiNetworkStateChangedListener(testListener); 2626 mActiveModeWarden.onNetworkStateChanged( 2627 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 2628 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_CONNECTED); 2629 verify(testListener).onWifiNetworkStateChanged( 2630 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 2631 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_CONNECTED); 2632 2633 // unregister listener and verify results no longer delivered 2634 mActiveModeWarden.removeWifiNetworkStateChangedListener(testListener); 2635 mActiveModeWarden.onNetworkStateChanged( 2636 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 2637 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_DISCONNECTED); 2638 verify(testListener, never()).onWifiNetworkStateChanged( 2639 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 2640 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_DISCONNECTED); 2641 } 2642 2643 /** 2644 * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through 2645 * the ActiveModeWarden.shutdownWifi() call when in STA mode. 2646 * When WiFi is in scan mode, calls to reset the wifi stack due to native failure 2647 * should trigger a supplicant stop, and subsequently, a driver reload. 2648 * Create and start WifiController in EnabledState, send command to restart WiFi 2649 * <p> 2650 * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and 2651 * ActiveModeWarden should enter SCAN_ONLY mode and the wifi driver should be started. 2652 */ 2653 @Test testRestartWifiStackInStaScanEnabledState()2654 public void testRestartWifiStackInStaScanEnabledState() throws Exception { 2655 assertInDisabledState(); 2656 2657 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 2658 mActiveModeWarden.scanAlwaysModeChanged(); 2659 mLooper.dispatchAll(); 2660 2661 assertInEnabledState(); 2662 verify(mWifiInjector).makeClientModeManager( 2663 any(), eq(new WorkSource(Process.WIFI_UID)), eq(ROLE_CLIENT_SCAN_ONLY), 2664 anyBoolean()); 2665 2666 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2667 true); 2668 mLooper.dispatchAll(); 2669 2670 verify(mClientModeManager).stop(); 2671 mClientListener.onStopped(mClientModeManager); 2672 mLooper.dispatchAll(); 2673 assertInDisabledState(); 2674 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2675 2676 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2677 mLooper.dispatchAll(); 2678 2679 verify(mWifiInjector, times(2)).makeClientModeManager(any(), any(), any(), anyBoolean()); 2680 assertInEnabledState(); 2681 2682 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2683 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2684 } 2685 2686 /** 2687 * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through 2688 * the ActiveModeWarden.shutdownWifi() call when in STA mode. 2689 * WiFi is in connect mode, calls to reset the wifi stack due to connection failures 2690 * should trigger a supplicant stop, and subsequently, a driver reload. 2691 * Create and start WifiController in EnabledState, send command to restart WiFi 2692 * <p> 2693 * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and 2694 * ActiveModeWarden should enter CONNECT_MODE and the wifi driver should be started. 2695 */ 2696 @Test testRestartWifiStackInStaConnectEnabledState()2697 public void testRestartWifiStackInStaConnectEnabledState() throws Exception { 2698 enableWifi(); 2699 assertInEnabledState(); 2700 verify(mWifiInjector).makeClientModeManager( 2701 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2702 2703 assertWifiShutDown(() -> { 2704 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2705 true); 2706 mLooper.dispatchAll(); 2707 // Complete the stop 2708 mClientListener.onStopped(mClientModeManager); 2709 mLooper.dispatchAll(); 2710 }); 2711 2712 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2713 2714 // still only started once 2715 verify(mWifiInjector).makeClientModeManager( 2716 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2717 2718 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2719 mLooper.dispatchAll(); 2720 2721 // started again 2722 verify(mWifiInjector, times(2)).makeClientModeManager(any(), any(), any(), anyBoolean()); 2723 assertInEnabledState(); 2724 2725 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2726 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2727 } 2728 2729 /** 2730 * The command to trigger WiFi restart on Bootup. 2731 * WiFi is in connect mode, calls to reset the wifi stack due to connection failures 2732 * should trigger a supplicant stop, and subsequently, a driver reload. (Reboot) 2733 * Create and start WifiController in EnabledState, start softAP and then 2734 * send command to restart WiFi 2735 * <p> 2736 * Expected: Wi-Fi should be restarted successfully on bootup. 2737 */ 2738 @Test testRestartWifiStackInStaConnectEnabledStatewithSap()2739 public void testRestartWifiStackInStaConnectEnabledStatewithSap() throws Exception { 2740 enableWifi(); 2741 assertInEnabledState(); 2742 verify(mWifiInjector).makeClientModeManager( 2743 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2744 2745 assertWifiShutDown(() -> { 2746 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2747 true); 2748 mLooper.dispatchAll(); 2749 // Complete the stop 2750 mClientListener.onStopped(mClientModeManager); 2751 mLooper.dispatchAll(); 2752 }); 2753 2754 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2755 2756 // still only started once 2757 verify(mWifiInjector).makeClientModeManager( 2758 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2759 2760 // start softAp 2761 enterSoftApActiveMode(); 2762 assertInEnabledState(); 2763 2764 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2765 mLooper.dispatchAll(); 2766 2767 // started again 2768 verify(mWifiInjector, times(2)).makeClientModeManager(any(), any(), any(), anyBoolean()); 2769 assertInEnabledState(); 2770 2771 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2772 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2773 } 2774 2775 /** 2776 * The command to trigger a WiFi reset should not trigger a reset when in ECM mode. 2777 * Enable wifi and enter ECM state, send command to restart wifi. 2778 * <p> 2779 * Expected: The command to trigger a wifi reset should be ignored and we should remain in ECM 2780 * mode. 2781 */ 2782 @Test testRestartWifiStackDoesNotExitECMMode()2783 public void testRestartWifiStackDoesNotExitECMMode() throws Exception { 2784 enableWifi(); 2785 assertInEnabledState(); 2786 verify(mWifiInjector).makeClientModeManager( 2787 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), eq(false)); 2788 2789 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 2790 assertEnteredEcmMode(() -> { 2791 emergencyCallStateChanged(true); 2792 mLooper.dispatchAll(); 2793 mClientListener.onStopped(mClientModeManager); 2794 mLooper.dispatchAll(); 2795 }); 2796 assertInEmergencyMode(); 2797 assertInDisabledState(); 2798 verify(mClientModeManager).stop(); 2799 verify(mClientModeManager, atLeastOnce()).getRole(); 2800 verify(mClientModeManager).clearWifiConnectedNetworkScorer(); 2801 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2802 2803 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG, 2804 false); 2805 mLooper.dispatchAll(); 2806 2807 // wasn't called again 2808 verify(mWifiInjector).makeClientModeManager( 2809 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2810 assertInEmergencyMode(); 2811 assertInDisabledState(); 2812 2813 verify(mClientModeManager, atLeastOnce()).getInterfaceName(); 2814 verify(mClientModeManager, atLeastOnce()).getPreviousRole(); 2815 } 2816 2817 /** 2818 * The command to trigger a WiFi reset should trigger a wifi reset in SoftApManager through 2819 * the ActiveModeWarden.shutdownWifi() call when in SAP enabled mode. 2820 */ 2821 @Test testRestartWifiStackInTetheredSoftApEnabledState()2822 public void testRestartWifiStackInTetheredSoftApEnabledState() throws Exception { 2823 enterSoftApActiveMode(); 2824 verify(mWifiInjector).makeSoftApManager( 2825 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2826 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 2827 // Return true to indicate Wifi recovery in progress 2828 when(mSelfRecovery.isRecoveryInProgress()).thenReturn(true); 2829 assertWifiShutDown(() -> { 2830 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2831 true); 2832 mLooper.dispatchAll(); 2833 // Complete the stop 2834 mSoftApListener.onStopped(mSoftApManager); 2835 mLooper.dispatchAll(); 2836 }); 2837 2838 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 2839 2840 // still only started once 2841 verify(mWifiInjector).makeSoftApManager( 2842 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2843 // No client mode manager created 2844 verify(mWifiInjector, never()).makeClientModeManager( 2845 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2846 2847 verify(mSelfRecovery).isRecoveryInProgress(); 2848 verify(mSelfRecovery).onWifiStopped(); 2849 2850 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2851 mLooper.dispatchAll(); 2852 2853 // started again 2854 verify(mWifiInjector, times(2)).makeSoftApManager( 2855 any(), any(), any(), any(), any(), anyBoolean()); 2856 assertInEnabledState(); 2857 2858 verify(mSelfRecovery).onRecoveryCompleted(); 2859 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2860 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2861 } 2862 2863 /** 2864 * The command to trigger a WiFi reset should trigger a wifi reset in SoftApManager through 2865 * the ActiveModeWarden.shutdownWifi() call when in SAP enabled mode. 2866 * If the shutdown isn't done fast enough to transit to disabled state it should still 2867 * bring up soft ap manager later. 2868 */ 2869 @Test testRestartWifiStackInTetheredSoftApEnabledState_SlowDisable()2870 public void testRestartWifiStackInTetheredSoftApEnabledState_SlowDisable() throws Exception { 2871 enterSoftApActiveMode(); 2872 verify(mWifiInjector).makeSoftApManager( 2873 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2874 2875 assertWifiShutDown(() -> { 2876 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2877 true); 2878 mLooper.dispatchAll(); 2879 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2880 mLooper.dispatchAll(); 2881 }); 2882 // Wifi is still not disabled yet. 2883 verify(mModeChangeCallback, never()).onActiveModeManagerRemoved(mSoftApManager); 2884 verify(mWifiInjector).makeSoftApManager( 2885 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2886 assertInEnabledState(); 2887 2888 // Now complete the stop and transit to disabled state 2889 mSoftApListener.onStopped(mSoftApManager); 2890 // mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2891 mLooper.dispatchAll(); 2892 2893 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 2894 // started again 2895 verify(mWifiInjector, times(1)).makeSoftApManager( 2896 any(), any(), any(), any(), any(), anyBoolean()); 2897 assertInDisabledState(); 2898 2899 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2900 mLooper.dispatchAll(); 2901 2902 // started again 2903 verify(mWifiInjector, times(2)).makeSoftApManager( 2904 any(), any(), any(), any(), any(), anyBoolean()); 2905 assertInEnabledState(); 2906 2907 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2908 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2909 } 2910 2911 /** 2912 * The command to trigger a WiFi reset should trigger a wifi reset in SoftApManager & 2913 * ClientModeManager through the ActiveModeWarden.shutdownWifi() call when in STA + SAP 2914 * enabled mode. 2915 */ 2916 @Test testRestartWifiStackInTetheredSoftApAndStaConnectEnabledState()2917 public void testRestartWifiStackInTetheredSoftApAndStaConnectEnabledState() throws Exception { 2918 enableWifi(); 2919 enterSoftApActiveMode(); 2920 verify(mWifiInjector).makeClientModeManager( 2921 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2922 verify(mWifiInjector).makeSoftApManager( 2923 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2924 2925 assertWifiShutDown(() -> { 2926 mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE, 2927 true); 2928 mLooper.dispatchAll(); 2929 // Complete the stop 2930 mClientListener.onStopped(mClientModeManager); 2931 mSoftApListener.onStopped(mSoftApManager); 2932 mLooper.dispatchAll(); 2933 }); 2934 2935 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 2936 verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager); 2937 2938 // still only started once 2939 verify(mWifiInjector).makeClientModeManager( 2940 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 2941 verify(mWifiInjector).makeSoftApManager( 2942 any(), any(), any(), eq(TEST_WORKSOURCE), eq(ROLE_SOFTAP_TETHERED), anyBoolean()); 2943 2944 mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS); 2945 mLooper.dispatchAll(); 2946 2947 // started again 2948 verify(mWifiInjector, times(2)).makeClientModeManager(any(), any(), any(), anyBoolean()); 2949 verify(mWifiInjector, times(2)).makeSoftApManager( 2950 any(), any(), any(), any(), any(), anyBoolean()); 2951 assertInEnabledState(); 2952 2953 verify(mSubsystemRestartCallback).onSubsystemRestarting(); 2954 verify(mSubsystemRestartCallback).onSubsystemRestarted(); 2955 } 2956 2957 /** 2958 * Tests that when Wifi is already disabled and another Wifi toggle command arrives, 2959 * don't enter scan mode if {@link WifiSettingsStore#isScanAlwaysAvailable()} is false. 2960 * Note: {@link WifiSettingsStore#isScanAlwaysAvailable()} returns false if either the wifi 2961 * scanning is disabled and airplane mode is on. 2962 */ 2963 @Test staDisabled_toggleWifiOff_scanNotAvailable_dontGoToScanMode()2964 public void staDisabled_toggleWifiOff_scanNotAvailable_dontGoToScanMode() { 2965 assertInDisabledState(); 2966 2967 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 2968 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 2969 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 2970 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 2971 2972 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 2973 mLooper.dispatchAll(); 2974 2975 assertInDisabledState(); 2976 verify(mWifiInjector, never()).makeClientModeManager( 2977 any(), eq(TEST_WORKSOURCE), any(), anyBoolean()); 2978 } 2979 2980 /** 2981 * Tests that when Wifi is already disabled and another Wifi toggle command arrives, 2982 * enter scan mode if {@link WifiSettingsStore#isScanAlwaysAvailable()} is true. 2983 * Note: {@link WifiSettingsStore#isScanAlwaysAvailable()} returns true if both the wifi 2984 * scanning is enabled and airplane mode is off. 2985 */ 2986 @Test staDisabled_toggleWifiOff_scanAvailable_goToScanMode()2987 public void staDisabled_toggleWifiOff_scanAvailable_goToScanMode() { 2988 assertInDisabledState(); 2989 2990 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 2991 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 2992 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 2993 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 2994 2995 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 2996 mLooper.dispatchAll(); 2997 2998 assertInEnabledState(); 2999 verify(mWifiInjector).makeClientModeManager( 3000 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_SCAN_ONLY), anyBoolean()); 3001 } 3002 3003 /** 3004 * Tests that if the carrier config to disable Wifi is enabled during ECM, Wifi is shut down 3005 * when entering ECM and turned back on when exiting ECM. 3006 */ 3007 @Test ecmDisablesWifi_exitEcm_restartWifi()3008 public void ecmDisablesWifi_exitEcm_restartWifi() throws Exception { 3009 enterClientModeActiveState(); 3010 3011 verify(mWifiInjector).makeClientModeManager( 3012 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 3013 3014 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 3015 assertEnteredEcmMode(() -> { 3016 emergencyCallbackModeChanged(true); 3017 mLooper.dispatchAll(); 3018 }); 3019 assertInEnabledState(); 3020 verify(mClientModeManager).stop(); 3021 3022 mClientListener.onStopped(mClientModeManager); 3023 mLooper.dispatchAll(); 3024 assertInDisabledState(); 3025 3026 emergencyCallbackModeChanged(false); 3027 mLooper.dispatchAll(); 3028 3029 assertNotInEmergencyMode(); 3030 // client mode restarted 3031 verify(mWifiInjector, times(2)).makeClientModeManager(any(), any(), any(), anyBoolean()); 3032 assertInEnabledState(); 3033 } 3034 3035 /** 3036 * Tests that if the carrier config to disable Wifi is not enabled during ECM, Wifi remains on 3037 * during ECM, and nothing happens after exiting ECM. 3038 */ 3039 @Test ecmDoesNotDisableWifi_exitEcm_noOp()3040 public void ecmDoesNotDisableWifi_exitEcm_noOp() throws Exception { 3041 enterClientModeActiveState(); 3042 3043 verify(mWifiInjector).makeClientModeManager( 3044 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 3045 3046 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 3047 assertEnteredEcmMode(() -> { 3048 emergencyCallbackModeChanged(true); 3049 mLooper.dispatchAll(); 3050 }); 3051 assertInEnabledState(); 3052 verify(mClientModeManager, never()).stop(); 3053 3054 emergencyCallbackModeChanged(false); 3055 mLooper.dispatchAll(); 3056 3057 assertNotInEmergencyMode(); 3058 // client mode manager not started again 3059 verify(mWifiInjector).makeClientModeManager( 3060 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 3061 assertInEnabledState(); 3062 } 3063 3064 @Test testUpdateCapabilityInSoftApActiveMode()3065 public void testUpdateCapabilityInSoftApActiveMode() throws Exception { 3066 SoftApCapability testCapability = new SoftApCapability(0); 3067 enterSoftApActiveMode(); 3068 mActiveModeWarden.updateSoftApCapability(testCapability, 3069 WifiManager.IFACE_IP_MODE_TETHERED); 3070 mLooper.dispatchAll(); 3071 verify(mSoftApManager).updateCapability(testCapability); 3072 } 3073 3074 @Test testUpdateConfigInSoftApActiveMode()3075 public void testUpdateConfigInSoftApActiveMode() throws Exception { 3076 SoftApConfiguration testConfig = new SoftApConfiguration.Builder() 3077 .setSsid("Test123").build(); 3078 enterSoftApActiveMode(); 3079 mActiveModeWarden.updateSoftApConfiguration(testConfig); 3080 mLooper.dispatchAll(); 3081 verify(mSoftApManager).updateConfiguration(testConfig); 3082 } 3083 3084 @Test testUpdateCapabilityInNonSoftApActiveMode()3085 public void testUpdateCapabilityInNonSoftApActiveMode() throws Exception { 3086 SoftApCapability testCapability = new SoftApCapability(0); 3087 enterClientModeActiveState(); 3088 mActiveModeWarden.updateSoftApCapability(testCapability, 3089 WifiManager.IFACE_IP_MODE_TETHERED); 3090 mLooper.dispatchAll(); 3091 verify(mSoftApManager, never()).updateCapability(any()); 3092 } 3093 3094 @Test testUpdateLocalModeSoftApCapabilityInTetheredSoftApActiveMode()3095 public void testUpdateLocalModeSoftApCapabilityInTetheredSoftApActiveMode() throws Exception { 3096 SoftApCapability testCapability = new SoftApCapability(0); 3097 enterSoftApActiveMode(); // Tethered mode 3098 mActiveModeWarden.updateSoftApCapability(testCapability, 3099 WifiManager.IFACE_IP_MODE_LOCAL_ONLY); 3100 mLooper.dispatchAll(); 3101 verify(mSoftApManager, never()).updateCapability(any()); 3102 } 3103 3104 @Test testUpdateConfigInNonSoftApActiveMode()3105 public void testUpdateConfigInNonSoftApActiveMode() throws Exception { 3106 SoftApConfiguration testConfig = new SoftApConfiguration.Builder() 3107 .setSsid("Test123").build(); 3108 enterClientModeActiveState(); 3109 mActiveModeWarden.updateSoftApConfiguration(testConfig); 3110 mLooper.dispatchAll(); 3111 verify(mSoftApManager, never()).updateConfiguration(any()); 3112 } 3113 3114 @Test isStaApConcurrencySupported()3115 public void isStaApConcurrencySupported() throws Exception { 3116 enterClientModeActiveState(); 3117 when(mWifiNative.isStaApConcurrencySupported()).thenReturn(false); 3118 mClientListener.onStarted(mClientModeManager); 3119 assertFalse(mActiveModeWarden.getSupportedFeatureSet() 3120 .get(WifiManager.WIFI_FEATURE_AP_STA)); 3121 3122 when(mWifiNative.isStaApConcurrencySupported()).thenReturn(true); 3123 mClientListener.onStarted(mClientModeManager); 3124 assertTrue(mActiveModeWarden.getSupportedFeatureSet() 3125 .get(WifiManager.WIFI_FEATURE_AP_STA)); 3126 } 3127 3128 @Test isStaStaConcurrencySupported()3129 public void isStaStaConcurrencySupported() throws Exception { 3130 // STA + STA not supported. 3131 when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(false); 3132 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForLocalOnlyConnections()); 3133 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForMbb()); 3134 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections()); 3135 3136 // STA + STA supported, but no use-cases enabled. 3137 when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(true); 3138 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForLocalOnlyConnections()); 3139 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForMbb()); 3140 assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections()); 3141 3142 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3143 .thenReturn(true); 3144 assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForLocalOnlyConnections()); 3145 3146 when(mWifiResourceCache.getBoolean( 3147 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3148 .thenReturn(true); 3149 assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForMbb()); 3150 3151 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3152 .thenReturn(true); 3153 assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections()); 3154 } 3155 requestAdditionalClientModeManager( ClientConnectivityRole additionaClientModeManagerRole, ConcreteClientModeManager additionalClientModeManager, ExternalClientModeManagerRequestListener externalRequestListener, String ssid, String bssid)3156 private Listener<ConcreteClientModeManager> requestAdditionalClientModeManager( 3157 ClientConnectivityRole additionaClientModeManagerRole, 3158 ConcreteClientModeManager additionalClientModeManager, 3159 ExternalClientModeManagerRequestListener externalRequestListener, 3160 String ssid, String bssid) 3161 throws Exception { 3162 enterClientModeActiveState(); 3163 when(additionalClientModeManager.getRequestorWs()).thenReturn(TEST_WORKSOURCE); 3164 3165 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 3166 new Mutable<>(); 3167 3168 // Connected to ssid1/bssid1 3169 WifiConfiguration config1 = new WifiConfiguration(); 3170 config1.SSID = TEST_SSID_1; 3171 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 3172 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 3173 3174 doAnswer((invocation) -> { 3175 Object[] args = invocation.getArguments(); 3176 additionalClientListener.value = 3177 (Listener<ConcreteClientModeManager>) args[0]; 3178 return additionalClientModeManager; 3179 }).when(mWifiInjector).makeClientModeManager( 3180 any(Listener.class), any(), any(), anyBoolean()); 3181 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 3182 when(additionalClientModeManager.getRole()).thenReturn(additionaClientModeManagerRole); 3183 3184 // request for ssid2/bssid2 3185 if (additionaClientModeManagerRole == ROLE_CLIENT_LOCAL_ONLY) { 3186 mActiveModeWarden.requestLocalOnlyClientModeManager( 3187 externalRequestListener, TEST_WORKSOURCE, ssid, bssid, false); 3188 } else if (additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3189 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3190 externalRequestListener, TEST_WORKSOURCE, ssid, bssid); 3191 } else if (additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3192 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3193 externalRequestListener, TEST_WORKSOURCE, ssid, bssid); 3194 } 3195 mLooper.dispatchAll(); 3196 verify(mWifiInjector) 3197 .makeClientModeManager(any(), eq(TEST_WORKSOURCE), 3198 eq(additionaClientModeManagerRole), anyBoolean()); 3199 additionalClientListener.value.onStarted(additionalClientModeManager); 3200 mLooper.dispatchAll(); 3201 // capture last use case set 3202 ArgumentCaptor<Integer> useCaseCaptor = ArgumentCaptor.forClass(Integer.class); 3203 verify(mWifiNative, atLeastOnce()).setMultiStaUseCase(useCaseCaptor.capture()); 3204 int lastUseCaseSet = useCaseCaptor.getValue().intValue(); 3205 // Ensure the hardware is correctly configured for STA + STA 3206 if (additionaClientModeManagerRole == ROLE_CLIENT_LOCAL_ONLY 3207 || additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3208 assertEquals(WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED, lastUseCaseSet); 3209 } else if (additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3210 assertEquals(WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY, lastUseCaseSet); 3211 } 3212 3213 // verify last set of primary connection is for WIFI_IFACE_NAME 3214 ArgumentCaptor<String> ifaceNameCaptor = ArgumentCaptor.forClass(String.class); 3215 verify(mWifiNative, atLeastOnce()).setMultiStaPrimaryConnection(ifaceNameCaptor.capture()); 3216 assertEquals(WIFI_IFACE_NAME, ifaceNameCaptor.getValue()); 3217 3218 // Returns the new local only client mode manager. 3219 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3220 ArgumentCaptor.forClass(ClientModeManager.class); 3221 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3222 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3223 // the additional CMM never became primary 3224 verify(mPrimaryChangedCallback, never()).onChange(any(), eq(additionalClientModeManager)); 3225 if (additionaClientModeManagerRole == ROLE_CLIENT_LOCAL_ONLY 3226 || additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3227 assertEquals(Set.of(TEST_WORKSOURCE), mActiveModeWarden.getSecondaryRequestWs()); 3228 } 3229 return additionalClientListener.value; 3230 } 3231 3232 @Test testRemoveDefaultClientModeManager()3233 public void testRemoveDefaultClientModeManager() throws Exception { 3234 // Ensure that we can create more client ifaces. 3235 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3236 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3237 .thenReturn(true); 3238 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3239 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3240 3241 // Verify removing a non DefaultClientModeManager works properly. 3242 requestRemoveAdditionalClientModeManager(ROLE_CLIENT_LOCAL_ONLY); 3243 3244 // Verify that a request to remove DefaultClientModeManager is ignored. 3245 ClientModeManager defaultClientModeManager = mock(DefaultClientModeManager.class); 3246 3247 mActiveModeWarden.removeClientModeManager(defaultClientModeManager); 3248 mLooper.dispatchAll(); 3249 verify(defaultClientModeManager, never()).stop(); 3250 } 3251 requestRemoveAdditionalClientModeManager( ClientConnectivityRole role)3252 private void requestRemoveAdditionalClientModeManager( 3253 ClientConnectivityRole role) throws Exception { 3254 ConcreteClientModeManager additionalClientModeManager = 3255 mock(ConcreteClientModeManager.class); 3256 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3257 ExternalClientModeManagerRequestListener.class); 3258 Listener<ConcreteClientModeManager> additionalClientListener = 3259 requestAdditionalClientModeManager(role, additionalClientModeManager, 3260 externalRequestListener, TEST_SSID_2, TEST_BSSID_2); 3261 3262 mActiveModeWarden.removeClientModeManager(additionalClientModeManager); 3263 mLooper.dispatchAll(); 3264 verify(additionalClientModeManager).stop(); 3265 additionalClientListener.onStopped(additionalClientModeManager); 3266 mLooper.dispatchAll(); 3267 verify(mModeChangeCallback).onActiveModeManagerRemoved(additionalClientModeManager); 3268 // the additional CMM still never became primary 3269 verify(mPrimaryChangedCallback, never()).onChange(any(), eq(additionalClientModeManager)); 3270 } 3271 requestRemoveAdditionalClientModeManagerWhenNotAllowed( ClientConnectivityRole role, boolean clientIsExpected, BitSet featureSet)3272 private void requestRemoveAdditionalClientModeManagerWhenNotAllowed( 3273 ClientConnectivityRole role, boolean clientIsExpected, 3274 BitSet featureSet) throws Exception { 3275 enterClientModeActiveState(false, featureSet); 3276 3277 // Connected to ssid1/bssid1 3278 WifiConfiguration config1 = new WifiConfiguration(); 3279 config1.SSID = TEST_SSID_1; 3280 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 3281 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 3282 3283 ConcreteClientModeManager additionalClientModeManager = 3284 mock(ConcreteClientModeManager.class); 3285 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 3286 new Mutable<>(); 3287 doAnswer((invocation) -> { 3288 Object[] args = invocation.getArguments(); 3289 additionalClientListener.value = 3290 (Listener<ConcreteClientModeManager>) args[0]; 3291 return additionalClientModeManager; 3292 }).when(mWifiInjector).makeClientModeManager( 3293 any(Listener.class), any(), any(), anyBoolean()); 3294 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 3295 when(additionalClientModeManager.getRole()).thenReturn(role); 3296 3297 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3298 ExternalClientModeManagerRequestListener.class); 3299 // request for ssid2/bssid2 3300 if (role == ROLE_CLIENT_LOCAL_ONLY) { 3301 mActiveModeWarden.requestLocalOnlyClientModeManager( 3302 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 3303 } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3304 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3305 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 3306 } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3307 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3308 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 3309 } 3310 mLooper.dispatchAll(); 3311 verifyNoMoreInteractions(additionalClientModeManager); 3312 // Returns the existing primary client mode manager. 3313 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3314 ArgumentCaptor.forClass(ClientModeManager.class); 3315 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3316 if (clientIsExpected) { 3317 assertEquals(mClientModeManager, requestedClientModeManager.getValue()); 3318 3319 mActiveModeWarden.removeClientModeManager(requestedClientModeManager.getValue()); 3320 } else { 3321 assertNull(requestedClientModeManager.getValue()); 3322 } 3323 mLooper.dispatchAll(); 3324 verifyNoMoreInteractions(additionalClientModeManager); 3325 } 3326 requestAdditionalClientModeManagerWhenWifiIsOff( ClientConnectivityRole role)3327 private void requestAdditionalClientModeManagerWhenWifiIsOff( 3328 ClientConnectivityRole role) throws Exception { 3329 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3330 ExternalClientModeManagerRequestListener.class); 3331 if (role == ROLE_CLIENT_LOCAL_ONLY) { 3332 mActiveModeWarden.requestLocalOnlyClientModeManager( 3333 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1, false); 3334 } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3335 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3336 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1); 3337 } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3338 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3339 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1); 3340 } 3341 mLooper.dispatchAll(); 3342 3343 verify(externalRequestListener).onAnswer(null); 3344 } 3345 requestAdditionalClientModeManagerWhenAlreadyPresent( ClientConnectivityRole role)3346 public void requestAdditionalClientModeManagerWhenAlreadyPresent( 3347 ClientConnectivityRole role) throws Exception { 3348 ConcreteClientModeManager additionalClientModeManager = 3349 mock(ConcreteClientModeManager.class); 3350 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3351 ExternalClientModeManagerRequestListener.class); 3352 requestAdditionalClientModeManager(role, additionalClientModeManager, 3353 externalRequestListener, TEST_SSID_2, TEST_BSSID_2); 3354 3355 // set additional CMM connected to ssid2/bssid2 3356 WifiConfiguration config2 = new WifiConfiguration(); 3357 config2.SSID = TEST_SSID_2; 3358 when(additionalClientModeManager.getConnectedWifiConfiguration()).thenReturn(config2); 3359 when(additionalClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_2); 3360 3361 // request for ssid3/bssid3 3362 // request for one more CMM (returns the existing one). 3363 if (role == ROLE_CLIENT_LOCAL_ONLY) { 3364 mActiveModeWarden.requestLocalOnlyClientModeManager( 3365 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_3, TEST_BSSID_3, false); 3366 } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3367 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3368 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_3, TEST_BSSID_3); 3369 } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3370 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3371 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_3, TEST_BSSID_3); 3372 } 3373 mLooper.dispatchAll(); 3374 3375 // Don't make another client mode manager. 3376 verify(mWifiInjector, times(1)) 3377 .makeClientModeManager(any(), any(), eq(role), anyBoolean()); 3378 // Returns the existing client mode manager. 3379 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3380 ArgumentCaptor.forClass(ClientModeManager.class); 3381 verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture()); 3382 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3383 } 3384 requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid( ClientConnectivityRole role)3385 public void requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid( 3386 ClientConnectivityRole role) throws Exception { 3387 ConcreteClientModeManager additionalClientModeManager = 3388 mock(ConcreteClientModeManager.class); 3389 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3390 ExternalClientModeManagerRequestListener.class); 3391 requestAdditionalClientModeManager(role, additionalClientModeManager, 3392 externalRequestListener, TEST_SSID_2, TEST_BSSID_2); 3393 3394 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3395 ArgumentCaptor.forClass(ClientModeManager.class); 3396 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3397 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3398 3399 // set additional CMM connected to ssid2/bssid2 3400 WifiConfiguration config2 = new WifiConfiguration(); 3401 config2.SSID = TEST_SSID_2; 3402 when(additionalClientModeManager.getConnectedWifiConfiguration()).thenReturn(config2); 3403 when(additionalClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_2); 3404 3405 // request for the same SSID/BSSID and expect the existing CMM to get returned twice. 3406 if (role == ROLE_CLIENT_LOCAL_ONLY) { 3407 mActiveModeWarden.requestLocalOnlyClientModeManager( 3408 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 3409 } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3410 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3411 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 3412 } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3413 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3414 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 3415 } 3416 mLooper.dispatchAll(); 3417 3418 // Don't make another client mode manager. 3419 verify(mWifiInjector, times(1)) 3420 .makeClientModeManager(any(), any(), eq(role), anyBoolean()); 3421 // Returns the existing client mode manager. 3422 verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture()); 3423 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3424 } 3425 requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid( ClientConnectivityRole role)3426 private void requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid( 3427 ClientConnectivityRole role) throws Exception { 3428 enterClientModeActiveState(); 3429 3430 // Connected to ssid1/bssid1 3431 WifiConfiguration config1 = new WifiConfiguration(); 3432 config1.SSID = TEST_SSID_1; 3433 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 3434 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 3435 3436 ConcreteClientModeManager additionalClientModeManager = 3437 mock(ConcreteClientModeManager.class); 3438 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 3439 new Mutable<>(); 3440 doAnswer((invocation) -> { 3441 Object[] args = invocation.getArguments(); 3442 additionalClientListener.value = 3443 (Listener<ConcreteClientModeManager>) args[0]; 3444 return additionalClientModeManager; 3445 }).when(mWifiInjector).makeClientModeManager( 3446 any(Listener.class), any(), any(), anyBoolean()); 3447 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 3448 when(additionalClientModeManager.getRole()).thenReturn(role); 3449 3450 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3451 ExternalClientModeManagerRequestListener.class); 3452 // request for same ssid1/bssid1 3453 if (role == ROLE_CLIENT_LOCAL_ONLY) { 3454 mActiveModeWarden.requestLocalOnlyClientModeManager( 3455 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1, false); 3456 } else if (role == ROLE_CLIENT_SECONDARY_LONG_LIVED) { 3457 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 3458 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1); 3459 } else if (role == ROLE_CLIENT_SECONDARY_TRANSIENT) { 3460 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3461 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1); 3462 } 3463 mLooper.dispatchAll(); 3464 verifyNoMoreInteractions(additionalClientModeManager); 3465 // Returns the existing primary client mode manager. 3466 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3467 ArgumentCaptor.forClass(ClientModeManager.class); 3468 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3469 assertEquals(mClientModeManager, requestedClientModeManager.getValue()); 3470 } 3471 3472 @Test requestRemoveLocalOnlyClientModeManager()3473 public void requestRemoveLocalOnlyClientModeManager() throws Exception { 3474 // Ensure that we can create more client ifaces. 3475 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3476 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3477 .thenReturn(true); 3478 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3479 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3480 3481 requestRemoveAdditionalClientModeManager(ROLE_CLIENT_LOCAL_ONLY); 3482 } 3483 3484 @Test requestRemoveLocalOnlyClientModeManagerWhenStaStaNotSupported()3485 public void requestRemoveLocalOnlyClientModeManagerWhenStaStaNotSupported() throws Exception { 3486 // Ensure that we cannot create more client ifaces. 3487 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 3488 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3489 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3490 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true, 3491 TEST_FEATURE_SET); 3492 } 3493 3494 @Test requestRemoveLocalOnlyClientModeManagerWhenFeatureDisabled()3495 public void requestRemoveLocalOnlyClientModeManagerWhenFeatureDisabled() throws Exception { 3496 // Ensure that we can create more client ifaces. 3497 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3498 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3499 .thenReturn(false); 3500 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3501 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3502 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true, 3503 TEST_FEATURE_SET); 3504 } 3505 3506 @Test testRequestSecondaryClientModeManagerWhenWifiIsDisabling()3507 public void testRequestSecondaryClientModeManagerWhenWifiIsDisabling() 3508 throws Exception { 3509 // Ensure that we can create more client ifaces. 3510 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3511 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3512 .thenReturn(true); 3513 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3514 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3515 3516 // Set wifi to disabling and verify secondary CMM is not obtained 3517 mActiveModeWarden.setWifiStateForApiCalls(WIFI_STATE_DISABLING); 3518 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3519 ExternalClientModeManagerRequestListener.class); 3520 mActiveModeWarden.requestLocalOnlyClientModeManager( 3521 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_1, TEST_BSSID_1, false); 3522 mLooper.dispatchAll(); 3523 3524 verify(externalRequestListener).onAnswer(null); 3525 } 3526 3527 @Test requestLocalOnlyClientModeManagerWhenWifiIsOff()3528 public void requestLocalOnlyClientModeManagerWhenWifiIsOff() throws Exception { 3529 // Ensure that we can create more client ifaces. 3530 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3531 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3532 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3533 3534 requestAdditionalClientModeManagerWhenWifiIsOff(ROLE_CLIENT_LOCAL_ONLY); 3535 } 3536 3537 @Test requestLocalOnlyClientModeManagerWhenAlreadyPresent()3538 public void requestLocalOnlyClientModeManagerWhenAlreadyPresent() throws Exception { 3539 // Ensure that we can create more client ifaces. 3540 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3541 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3542 .thenReturn(true); 3543 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3544 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3545 3546 requestAdditionalClientModeManagerWhenAlreadyPresent(ROLE_CLIENT_LOCAL_ONLY); 3547 } 3548 3549 @Test requestLocalOnlyClientModeManagerWhenAlreadyPresentSameBssid()3550 public void requestLocalOnlyClientModeManagerWhenAlreadyPresentSameBssid() throws Exception { 3551 // Ensure that we can create more client ifaces. 3552 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3553 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3554 .thenReturn(true); 3555 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3556 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3557 3558 requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid(ROLE_CLIENT_LOCAL_ONLY); 3559 } 3560 3561 @Test requestLocalOnlyClientModeManagerWhenConnectingToPrimaryBssid()3562 public void requestLocalOnlyClientModeManagerWhenConnectingToPrimaryBssid() throws Exception { 3563 // Ensure that we can create more client ifaces. 3564 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3565 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3566 .thenReturn(true); 3567 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3568 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3569 3570 requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid(ROLE_CLIENT_LOCAL_ONLY); 3571 } 3572 3573 @Test requestRemoveLocalOnlyClientModeManagerWhenNotSystemAppAndTargetSdkLessThanS()3574 public void requestRemoveLocalOnlyClientModeManagerWhenNotSystemAppAndTargetSdkLessThanS() 3575 throws Exception { 3576 // Ensure that we can create more client ifaces. 3577 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3578 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3579 .thenReturn(true); 3580 3581 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 3582 when(mWifiPermissionsUtil.isTargetSdkLessThan( 3583 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 3584 .thenReturn(true); 3585 when(mWifiPermissionsUtil.isTargetSdkLessThan( 3586 "system-service", Build.VERSION_CODES.S, Process.SYSTEM_UID)) 3587 .thenReturn(false); 3588 // Simulate explicit user approval 3589 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3590 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, true)); 3591 WorkSource workSource = new WorkSource(TEST_WORKSOURCE); 3592 workSource.add(SETTINGS_WORKSOURCE); 3593 verify(mWifiNative).isItPossibleToCreateStaIface(eq(workSource)); 3594 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, 3595 true, TEST_FEATURE_SET); 3596 } 3597 3598 @Test requestRemoveLocalOnlyClientModeManagerWhenNotSystemAppAndTargetSdkEqualToS()3599 public void requestRemoveLocalOnlyClientModeManagerWhenNotSystemAppAndTargetSdkEqualToS() 3600 throws Exception { 3601 // Ensure that we can create more client ifaces. 3602 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3603 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3604 .thenReturn(true); 3605 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 3606 when(mWifiPermissionsUtil.isTargetSdkLessThan( 3607 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 3608 .thenReturn(false); 3609 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3610 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3611 requestRemoveAdditionalClientModeManager(ROLE_CLIENT_LOCAL_ONLY); 3612 } 3613 3614 @Test requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkLessThanSAndCantCreate()3615 public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkLessThanSAndCantCreate() 3616 throws Exception { 3617 // Ensure that we can't create more client ifaces - so will attempt to fallback (which we 3618 // should be able to do for <S apps) 3619 when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(true); 3620 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 3621 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3622 .thenReturn(true); 3623 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 3624 when(mWifiPermissionsUtil.isTargetSdkLessThan( 3625 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 3626 .thenReturn(true); 3627 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3628 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3629 BitSet expectedFeatureSet = addCapabilitiesToBitset( 3630 TEST_FEATURE_SET, WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY); 3631 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, 3632 true, expectedFeatureSet); 3633 } 3634 testLoFallbackAboveAndroidS(boolean isStaStaSupported)3635 private void testLoFallbackAboveAndroidS(boolean isStaStaSupported) throws Exception { 3636 when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(isStaStaSupported); 3637 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 3638 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3639 .thenReturn(true); 3640 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 3641 when(mWifiPermissionsUtil.isTargetSdkLessThan( 3642 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 3643 .thenReturn(false); 3644 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3645 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3646 BitSet expectedFeatureSet = (BitSet) TEST_FEATURE_SET.clone(); 3647 if (isStaStaSupported) { 3648 expectedFeatureSet.set(WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY); 3649 } 3650 3651 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, 3652 !isStaStaSupported, 3653 expectedFeatureSet); 3654 } 3655 3656 @Test requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate()3657 public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate() 3658 throws Exception { 3659 // Ensure that we can't create more client ifaces - so will attempt to fallback (which we 3660 // can't for >=S apps) 3661 testLoFallbackAboveAndroidS(true); 3662 } 3663 3664 @Test requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate2()3665 public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate2() 3666 throws Exception { 3667 // Ensure that we can't create more client ifaces and STA+STA is not supported, we 3668 // fallback even for >=S apps 3669 testLoFallbackAboveAndroidS(false); 3670 } 3671 3672 @Test requestRemoveSecondaryLongLivedClientModeManager()3673 public void requestRemoveSecondaryLongLivedClientModeManager() throws Exception { 3674 // Ensure that we can create more client ifaces. 3675 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3676 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3677 .thenReturn(true); 3678 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3679 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3680 3681 requestRemoveAdditionalClientModeManager(ROLE_CLIENT_SECONDARY_LONG_LIVED); 3682 } 3683 3684 @Test requestRemoveSecondaryLongLivedClientModeManagerWhenStaStaNotSupported()3685 public void requestRemoveSecondaryLongLivedClientModeManagerWhenStaStaNotSupported() 3686 throws Exception { 3687 // Ensure that we cannot create more client ifaces. 3688 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 3689 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3690 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3691 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_LONG_LIVED, 3692 true, TEST_FEATURE_SET); 3693 } 3694 3695 @Test requestRemoveSecondaryLongLivedClientModeManagerWhenFeatureDisabled()3696 public void requestRemoveSecondaryLongLivedClientModeManagerWhenFeatureDisabled() 3697 throws Exception { 3698 // Ensure that we can create more client ifaces. 3699 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3700 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3701 .thenReturn(false); 3702 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3703 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3704 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_LONG_LIVED, 3705 true, TEST_FEATURE_SET); 3706 } 3707 3708 @Test requestSecondaryLongLivedClientModeManagerWhenWifiIsOff()3709 public void requestSecondaryLongLivedClientModeManagerWhenWifiIsOff() throws Exception { 3710 // Ensure that we can create more client ifaces. 3711 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3712 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3713 .thenReturn(true); 3714 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3715 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3716 3717 requestAdditionalClientModeManagerWhenWifiIsOff(ROLE_CLIENT_SECONDARY_LONG_LIVED); 3718 } 3719 3720 @Test requestSecondaryLongLivedClientModeManagerWhenAlreadyPresent()3721 public void requestSecondaryLongLivedClientModeManagerWhenAlreadyPresent() throws Exception { 3722 // Ensure that we can create more client ifaces. 3723 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3724 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3725 .thenReturn(true); 3726 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3727 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3728 3729 requestAdditionalClientModeManagerWhenAlreadyPresent(ROLE_CLIENT_SECONDARY_LONG_LIVED); 3730 } 3731 3732 @Test requestSecondaryLongLivedClientModeManagerWhenAlreadyPresentSameBssid()3733 public void requestSecondaryLongLivedClientModeManagerWhenAlreadyPresentSameBssid() 3734 throws Exception { 3735 // Ensure that we can create more client ifaces. 3736 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3737 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3738 .thenReturn(true); 3739 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3740 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3741 3742 requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid( 3743 ROLE_CLIENT_SECONDARY_LONG_LIVED); 3744 } 3745 3746 @Test requestSecondaryLongLivedClientModeManagerWhenConnectingToPrimaryBssid()3747 public void requestSecondaryLongLivedClientModeManagerWhenConnectingToPrimaryBssid() 3748 throws Exception { 3749 // Ensure that we can create more client ifaces. 3750 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3751 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 3752 .thenReturn(true); 3753 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3754 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 3755 3756 requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid( 3757 ROLE_CLIENT_SECONDARY_LONG_LIVED); 3758 } 3759 3760 @Test requestRemoveSecondaryTransientClientModeManager()3761 public void requestRemoveSecondaryTransientClientModeManager() throws Exception { 3762 // Ensure that we can create more client ifaces. 3763 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3764 when(mWifiResourceCache.getBoolean( 3765 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3766 .thenReturn(true); 3767 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3768 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3769 3770 requestRemoveAdditionalClientModeManager(ROLE_CLIENT_SECONDARY_TRANSIENT); 3771 } 3772 3773 @Test requestRemoveSecondaryTransientClientModeManagerWhenStaStaNotSupported()3774 public void requestRemoveSecondaryTransientClientModeManagerWhenStaStaNotSupported() 3775 throws Exception { 3776 // Ensure that we cannot create more client ifaces. 3777 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 3778 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3779 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3780 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_TRANSIENT, 3781 true, TEST_FEATURE_SET); 3782 } 3783 3784 @Test requestRemoveSecondaryTransientClientModeManagerWhenFeatureDisabled()3785 public void requestRemoveSecondaryTransientClientModeManagerWhenFeatureDisabled() 3786 throws Exception { 3787 // Ensure that we can create more client ifaces. 3788 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3789 when(mWifiResourceCache.getBoolean( 3790 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3791 .thenReturn(false); 3792 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3793 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3794 requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_TRANSIENT, 3795 true, TEST_FEATURE_SET); 3796 } 3797 3798 @Test requestSecondaryTransientClientModeManagerWhenWifiIsOff()3799 public void requestSecondaryTransientClientModeManagerWhenWifiIsOff() throws Exception { 3800 // Ensure that we can create more client ifaces. 3801 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3802 when(mWifiResourceCache.getBoolean( 3803 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3804 .thenReturn(true); 3805 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3806 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3807 3808 requestAdditionalClientModeManagerWhenWifiIsOff(ROLE_CLIENT_SECONDARY_TRANSIENT); 3809 } 3810 3811 @Test requestSecondaryTransientClientModeManagerWhenAlreadyPresent()3812 public void requestSecondaryTransientClientModeManagerWhenAlreadyPresent() throws Exception { 3813 // Ensure that we can create more client ifaces. 3814 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3815 when(mWifiResourceCache.getBoolean( 3816 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3817 .thenReturn(true); 3818 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3819 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3820 3821 requestAdditionalClientModeManagerWhenAlreadyPresent(ROLE_CLIENT_SECONDARY_TRANSIENT); 3822 } 3823 3824 @Test requestSecondaryTransientClientModeManagerWhenAlreadyPresentSameBssid()3825 public void requestSecondaryTransientClientModeManagerWhenAlreadyPresentSameBssid() 3826 throws Exception { 3827 // Ensure that we can create more client ifaces. 3828 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3829 when(mWifiResourceCache.getBoolean( 3830 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3831 .thenReturn(true); 3832 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3833 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3834 3835 requestAdditionalClientModeManagerWhenAlreadyPresentSameBssid( 3836 ROLE_CLIENT_SECONDARY_TRANSIENT); 3837 } 3838 3839 @Test requestSecondaryTransientClientModeManagerWhenConnectingToPrimaryBssid()3840 public void requestSecondaryTransientClientModeManagerWhenConnectingToPrimaryBssid() 3841 throws Exception { 3842 // Ensure that we can create more client ifaces. 3843 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3844 when(mWifiResourceCache.getBoolean( 3845 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3846 .thenReturn(true); 3847 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3848 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3849 3850 requestAdditionalClientModeManagerWhenConnectingToPrimaryBssid( 3851 ROLE_CLIENT_SECONDARY_TRANSIENT); 3852 } 3853 3854 @Test requestHighPrioSecondaryTransientClientModeManagerWhenConnectedToLocalOnlyBssid()3855 public void requestHighPrioSecondaryTransientClientModeManagerWhenConnectedToLocalOnlyBssid() 3856 throws Exception { 3857 // Ensure that we can create more client ifaces. 3858 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3859 when(mWifiResourceCache.getBoolean( 3860 R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3861 .thenReturn(true); 3862 when(mWifiResourceCache.getBoolean( 3863 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3864 .thenReturn(true); 3865 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3866 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3867 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3868 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3869 3870 enterClientModeActiveState(); 3871 3872 // Primary Connected to ssid1/bssid1 3873 WifiConfiguration config1 = new WifiConfiguration(); 3874 config1.SSID = TEST_SSID_1; 3875 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 3876 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 3877 3878 ConcreteClientModeManager additionalClientModeManager = 3879 mock(ConcreteClientModeManager.class); 3880 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener1 = 3881 new Mutable<>(); 3882 doAnswer((invocation) -> { 3883 Object[] args = invocation.getArguments(); 3884 additionalClientListener1.value = 3885 (Listener<ConcreteClientModeManager>) args[0]; 3886 return additionalClientModeManager; 3887 }).when(mWifiInjector).makeClientModeManager( 3888 any(Listener.class), any(), eq(ROLE_CLIENT_LOCAL_ONLY), 3889 anyBoolean()); 3890 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 3891 3892 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3893 ExternalClientModeManagerRequestListener.class); 3894 // request for ssid2/bssid2 3895 mActiveModeWarden.requestLocalOnlyClientModeManager( 3896 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 3897 mLooper.dispatchAll(); 3898 verify(mWifiInjector).makeClientModeManager( 3899 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 3900 additionalClientListener1.value.onStarted(additionalClientModeManager); 3901 mLooper.dispatchAll(); 3902 // Returns the new client mode manager. 3903 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3904 ArgumentCaptor.forClass(ClientModeManager.class); 3905 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3906 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3907 3908 // set additional CMM connected to ssid2/bssid2 3909 WifiConfiguration config2 = new WifiConfiguration(); 3910 config2.SSID = TEST_SSID_2; 3911 when(additionalClientModeManager.getConnectedWifiConfiguration()).thenReturn(config2); 3912 when(additionalClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_2); 3913 3914 // request for same ssid2/bssid2 for a different role. 3915 // request for one more CMM (should return the existing local only one). 3916 mActiveModeWarden.requestSecondaryTransientClientModeManager( 3917 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 3918 mLooper.dispatchAll(); 3919 3920 // Don't make another client mode manager, but should switch role of existing client mode 3921 // manager. 3922 verify(mWifiInjector, never()) 3923 .makeClientModeManager(any(), any(), eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 3924 anyBoolean()); 3925 ArgumentCaptor<Listener<ConcreteClientModeManager>> 3926 additionalClientListener2 = ArgumentCaptor.forClass( 3927 Listener.class); 3928 verify(additionalClientModeManager).setRole(eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 3929 eq(TEST_WORKSOURCE), additionalClientListener2.capture()); 3930 3931 // Simulate completion of role switch. 3932 additionalClientListener2.getValue().onRoleChanged(additionalClientModeManager); 3933 3934 // Returns the existing client mode manager. 3935 verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture()); 3936 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3937 } 3938 3939 @Test requestLowPrioSecondaryTransientClientModeManagerWhenConnectedToLocalOnlyBssid()3940 public void requestLowPrioSecondaryTransientClientModeManagerWhenConnectedToLocalOnlyBssid() 3941 throws Exception { 3942 // Ensure that we can create more client ifaces. 3943 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 3944 when(mWifiResourceCache.getBoolean( 3945 R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 3946 .thenReturn(true); 3947 when(mWifiResourceCache.getBoolean( 3948 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 3949 .thenReturn(true); 3950 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3951 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 3952 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 3953 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 3954 3955 enterClientModeActiveState(); 3956 3957 // Primary Connected to ssid1/bssid1 3958 WifiConfiguration config1 = new WifiConfiguration(); 3959 config1.SSID = TEST_SSID_1; 3960 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 3961 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 3962 3963 ConcreteClientModeManager additionalClientModeManager = 3964 mock(ConcreteClientModeManager.class); 3965 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener1 = 3966 new Mutable<>(); 3967 doAnswer((invocation) -> { 3968 Object[] args = invocation.getArguments(); 3969 additionalClientListener1.value = 3970 (Listener<ConcreteClientModeManager>) args[0]; 3971 return additionalClientModeManager; 3972 }).when(mWifiInjector).makeClientModeManager( 3973 any(Listener.class), any(), eq(ROLE_CLIENT_LOCAL_ONLY), 3974 anyBoolean()); 3975 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 3976 3977 ExternalClientModeManagerRequestListener externalRequestListener = mock( 3978 ExternalClientModeManagerRequestListener.class); 3979 // request for ssid2/bssid2 3980 mActiveModeWarden.requestLocalOnlyClientModeManager( 3981 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 3982 mLooper.dispatchAll(); 3983 verify(mWifiInjector).makeClientModeManager( 3984 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 3985 additionalClientListener1.value.onStarted(additionalClientModeManager); 3986 mLooper.dispatchAll(); 3987 // Returns the new client mode manager. 3988 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 3989 ArgumentCaptor.forClass(ClientModeManager.class); 3990 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 3991 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 3992 3993 // set additional CMM connected to ssid2/bssid2 3994 WifiConfiguration config2 = new WifiConfiguration(); 3995 config2.SSID = TEST_SSID_2; 3996 when(additionalClientModeManager.getConnectedWifiConfiguration()).thenReturn(config2); 3997 when(additionalClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_2); 3998 3999 // Now, deny the creation of STA for the new request 4000 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false); 4001 4002 // request for same ssid2/bssid2 for a different role. 4003 // request for one more CMM (should return null). 4004 mActiveModeWarden.requestSecondaryTransientClientModeManager( 4005 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4006 mLooper.dispatchAll(); 4007 4008 // Don't make another client mode manager or change role 4009 verify(mWifiInjector, never()) 4010 .makeClientModeManager(any(), any(), eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 4011 anyBoolean()); 4012 verify(additionalClientModeManager, never()).setRole(eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 4013 eq(TEST_WORKSOURCE), any()); 4014 4015 // Ensure the request is rejected. 4016 verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture()); 4017 assertNull(requestedClientModeManager.getValue()); 4018 } 4019 4020 @Test requestSecondaryTransientClientModeManagerWhenDppInProgress()4021 public void requestSecondaryTransientClientModeManagerWhenDppInProgress() 4022 throws Exception { 4023 // Ensure that we can create more client ifaces. 4024 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4025 when(mWifiResourceCache.getBoolean( 4026 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 4027 .thenReturn(true); 4028 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4029 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 4030 4031 // Create primary STA. 4032 enterClientModeActiveState(); 4033 4034 // Start DPP session 4035 when(mDppManager.isSessionInProgress()).thenReturn(true); 4036 4037 // request secondary transient CMM creation. 4038 ConcreteClientModeManager additionalClientModeManager = 4039 mock(ConcreteClientModeManager.class); 4040 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4041 new Mutable<>(); 4042 doAnswer((invocation) -> { 4043 Object[] args = invocation.getArguments(); 4044 additionalClientListener.value = 4045 (Listener<ConcreteClientModeManager>) args[0]; 4046 return additionalClientModeManager; 4047 }).when(mWifiInjector).makeClientModeManager( 4048 any(Listener.class), any(), eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 4049 anyBoolean()); 4050 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4051 4052 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4053 ExternalClientModeManagerRequestListener.class); 4054 mActiveModeWarden.requestSecondaryTransientClientModeManager( 4055 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4056 mLooper.dispatchAll(); 4057 4058 // verify that we did not create a secondary CMM. 4059 verifyNoMoreInteractions(additionalClientModeManager); 4060 // Returns the existing primary client mode manager. 4061 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4062 ArgumentCaptor.forClass(ClientModeManager.class); 4063 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4064 assertEquals(mClientModeManager, requestedClientModeManager.getValue()); 4065 4066 // Stop ongoing DPP session. 4067 when(mDppManager.isSessionInProgress()).thenReturn(false); 4068 4069 // request secondary transient CMM creation again, now it should be allowed. 4070 mActiveModeWarden.requestSecondaryTransientClientModeManager( 4071 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4072 mLooper.dispatchAll(); 4073 verify(mWifiInjector) 4074 .makeClientModeManager(any(), eq(TEST_WORKSOURCE), 4075 eq(ROLE_CLIENT_SECONDARY_TRANSIENT), anyBoolean()); 4076 additionalClientListener.value.onStarted(additionalClientModeManager); 4077 mLooper.dispatchAll(); 4078 // Returns the new secondary client mode manager. 4079 verify(externalRequestListener, times(2)).onAnswer(requestedClientModeManager.capture()); 4080 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 4081 } 4082 4083 @Test testRequestForSecondaryLocalOnlyForEnterCarModePrioritized()4084 public void testRequestForSecondaryLocalOnlyForEnterCarModePrioritized() throws Exception { 4085 // mock caller to have ENTER_CAR_MODE_PRIORITIZED 4086 when(mWifiPermissionsUtil.checkEnterCarModePrioritized(anyInt())).thenReturn(true); 4087 // Ensure that we can create more client ifaces. 4088 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4089 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 4090 .thenReturn(true); 4091 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 4092 .thenReturn(true); 4093 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4094 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 4095 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4096 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 4097 4098 enterClientModeActiveState(); 4099 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4100 ArgumentCaptor.forClass(ClientModeManager.class); 4101 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4102 ExternalClientModeManagerRequestListener.class); 4103 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4104 new Mutable<>(); 4105 ConcreteClientModeManager additionalClientModeManager = 4106 mock(ConcreteClientModeManager.class); 4107 doAnswer((invocation) -> { 4108 Object[] args = invocation.getArguments(); 4109 additionalClientListener.value = 4110 (Listener<ConcreteClientModeManager>) args[0]; 4111 return additionalClientModeManager; 4112 }).when(mWifiInjector).makeClientModeManager( 4113 any(Listener.class), any(), any(), anyBoolean()); 4114 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 4115 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 4116 4117 // mock requesting local only secondary 4118 mActiveModeWarden.requestLocalOnlyClientModeManager( 4119 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 4120 mLooper.dispatchAll(); 4121 // Verify the primary is given to the externalRequestListener 4122 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4123 verify(mWifiInjector, never()).makeClientModeManager( 4124 any(), any(), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 4125 assertEquals(ROLE_CLIENT_PRIMARY, requestedClientModeManager.getValue().getRole()); 4126 4127 // Request for non local-only STA and verify the secondary STA is provided instead. 4128 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 4129 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 4130 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4131 mLooper.dispatchAll(); 4132 verify(mWifiInjector).makeClientModeManager(any(), any(), 4133 eq(ROLE_CLIENT_SECONDARY_LONG_LIVED), anyBoolean()); 4134 4135 additionalClientListener.value.onStarted(additionalClientModeManager); 4136 mLooper.dispatchAll(); 4137 verify(externalRequestListener, times(2)).onAnswer( 4138 requestedClientModeManager.capture()); 4139 assertEquals(ROLE_CLIENT_SECONDARY_LONG_LIVED, 4140 requestedClientModeManager.getValue().getRole()); 4141 } 4142 4143 @Test testRequestForSecondaryLocalOnlyForShell()4144 public void testRequestForSecondaryLocalOnlyForShell() throws Exception { 4145 // mock caller to have ENTER_CAR_MODE_PRIORITIZED 4146 when(mWifiPermissionsUtil.checkEnterCarModePrioritized(anyInt())).thenReturn(true); 4147 // Ensure that we can create more client ifaces. 4148 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4149 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 4150 .thenReturn(true); 4151 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 4152 .thenReturn(true); 4153 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4154 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false)); 4155 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4156 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 4157 4158 enterClientModeActiveState(); 4159 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4160 ArgumentCaptor.forClass(ClientModeManager.class); 4161 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4162 ExternalClientModeManagerRequestListener.class); 4163 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4164 new Mutable<>(); 4165 ConcreteClientModeManager additionalClientModeManager = 4166 mock(ConcreteClientModeManager.class); 4167 doAnswer((invocation) -> { 4168 Object[] args = invocation.getArguments(); 4169 additionalClientListener.value = 4170 (Listener<ConcreteClientModeManager>) args[0]; 4171 return additionalClientModeManager; 4172 }).when(mWifiInjector).makeClientModeManager( 4173 any(Listener.class), any(), any(), anyBoolean()); 4174 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 4175 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 4176 4177 // Request will shell uid for local-only STA and verify the secondary is provided instead. 4178 WorkSource shellWs = new WorkSource(0, "shell"); 4179 mActiveModeWarden.requestLocalOnlyClientModeManager( 4180 externalRequestListener, shellWs, TEST_SSID_2, TEST_BSSID_2, false); 4181 mLooper.dispatchAll(); 4182 verify(mWifiInjector).makeClientModeManager(any(), any(), 4183 eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 4184 additionalClientListener.value.onStarted(additionalClientModeManager); 4185 mLooper.dispatchAll(); 4186 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4187 verify(mWifiInjector).makeClientModeManager( 4188 any(), any(), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 4189 assertEquals(ROLE_CLIENT_LOCAL_ONLY, requestedClientModeManager.getValue().getRole()); 4190 } 4191 4192 @Test configureHwOnMbbSwitch()4193 public void configureHwOnMbbSwitch() 4194 throws Exception { 4195 // Ensure that we can create more client ifaces. 4196 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4197 when(mWifiResourceCache.getBoolean( 4198 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 4199 .thenReturn(true); 4200 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4201 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 4202 4203 ConcreteClientModeManager additionalClientModeManager = 4204 mock(ConcreteClientModeManager.class); 4205 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4206 ExternalClientModeManagerRequestListener.class); 4207 Listener<ConcreteClientModeManager> additionalClientListener = 4208 requestAdditionalClientModeManager(ROLE_CLIENT_SECONDARY_TRANSIENT, 4209 additionalClientModeManager, externalRequestListener, TEST_SSID_2, 4210 TEST_BSSID_2); 4211 4212 // Now simulate the MBB role switch. 4213 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4214 mClientListener.onRoleChanged(mClientModeManager); 4215 4216 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 4217 additionalClientListener.onRoleChanged(additionalClientModeManager); 4218 4219 // verify last use case set is PREFER_PRIMARY 4220 ArgumentCaptor<Integer> useCaseCaptor = ArgumentCaptor.forClass(Integer.class); 4221 verify(mWifiNative, atLeastOnce()).setMultiStaUseCase(useCaseCaptor.capture()); 4222 int lastUseCaseSet = useCaseCaptor.getValue().intValue(); 4223 assertEquals(WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY, lastUseCaseSet); 4224 4225 // verify last set of primary connection is for WIFI_IFACE_NAME_1 4226 ArgumentCaptor<String> ifaceNameCaptor = ArgumentCaptor.forClass(String.class); 4227 verify(mWifiNative, atLeastOnce()).setMultiStaPrimaryConnection(ifaceNameCaptor.capture()); 4228 assertEquals(WIFI_IFACE_NAME_1, ifaceNameCaptor.getValue()); 4229 } 4230 4231 @Test airplaneModeToggleOnDisablesWifi()4232 public void airplaneModeToggleOnDisablesWifi() throws Exception { 4233 enterClientModeActiveState(); 4234 assertInEnabledState(); 4235 4236 assertWifiShutDown(() -> { 4237 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 4238 mActiveModeWarden.airplaneModeToggled(); 4239 mLooper.dispatchAll(); 4240 }); 4241 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), anyInt(), 4242 anyInt(), eq("android_apm"), eq(false)); 4243 4244 mClientListener.onStopped(mClientModeManager); 4245 mLooper.dispatchAll(); 4246 assertInDisabledState(); 4247 } 4248 4249 @Test testGetActiveModeManagersOrder()4250 public void testGetActiveModeManagersOrder() throws Exception { 4251 enableWifi(); 4252 enterSoftApActiveMode(); 4253 assertInEnabledState(); 4254 4255 Collection<ActiveModeManager> activeModeManagers = 4256 mActiveModeWarden.getActiveModeManagers(); 4257 if (activeModeManagers == null) { 4258 fail("activeModeManagers list should not be null"); 4259 } 4260 Object[] modeManagers = activeModeManagers.toArray(); 4261 assertEquals(2, modeManagers.length); 4262 assertTrue(modeManagers[0] instanceof SoftApManager); 4263 assertTrue(modeManagers[1] instanceof ConcreteClientModeManager); 4264 } 4265 4266 @Test airplaneModeToggleOnDisablesSoftAp()4267 public void airplaneModeToggleOnDisablesSoftAp() throws Exception { 4268 enterSoftApActiveMode(); 4269 assertInEnabledState(); 4270 4271 assertWifiShutDown(() -> { 4272 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 4273 mActiveModeWarden.airplaneModeToggled(); 4274 mLooper.dispatchAll(); 4275 }); 4276 4277 mSoftApListener.onStopped(mSoftApManager); 4278 mLooper.dispatchAll(); 4279 assertInDisabledState(); 4280 } 4281 4282 @Test airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithOneModeManager()4283 public void airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithOneModeManager() 4284 throws Exception { 4285 enterClientModeActiveState(); 4286 assertInEnabledState(); 4287 4288 // APM toggle on 4289 assertWifiShutDown(() -> { 4290 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 4291 mActiveModeWarden.airplaneModeToggled(); 4292 mLooper.dispatchAll(); 4293 }); 4294 4295 4296 // APM toggle off before the stop is complete. 4297 assertInEnabledState(); 4298 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 4299 mActiveModeWarden.airplaneModeToggled(); 4300 mLooper.dispatchAll(); 4301 4302 mClientListener.onStopped(mClientModeManager); 4303 mLooper.dispatchAll(); 4304 4305 verify(mWifiInjector, times(2)).makeClientModeManager( 4306 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 4307 4308 mClientListener.onStarted(mClientModeManager); 4309 mLooper.dispatchAll(); 4310 4311 // We should be back to enabled state. 4312 assertInEnabledState(); 4313 } 4314 4315 @Test airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithOneModeManager2()4316 public void airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithOneModeManager2() 4317 throws Exception { 4318 enterClientModeActiveState(); 4319 assertInEnabledState(); 4320 4321 // APM toggle on 4322 assertWifiShutDown(() -> { 4323 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 4324 mActiveModeWarden.airplaneModeToggled(); 4325 mLooper.dispatchAll(); 4326 }); 4327 4328 4329 // APM toggle off before the stop is complete. 4330 assertInEnabledState(); 4331 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 4332 mActiveModeWarden.airplaneModeToggled(); 4333 // This test is identical to 4334 // airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithOneModeManager, except the 4335 // dispatchAll() here is removed. There could be a race between airplaneModeToggled and 4336 // mClientListener.onStopped(). See b/160105640#comment5. 4337 4338 mClientListener.onStopped(mClientModeManager); 4339 mLooper.dispatchAll(); 4340 4341 verify(mWifiInjector, times(2)).makeClientModeManager( 4342 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 4343 4344 mClientListener.onStarted(mClientModeManager); 4345 mLooper.dispatchAll(); 4346 4347 // We should be back to enabled state. 4348 assertInEnabledState(); 4349 } 4350 4351 @Test airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithTwoModeManager()4352 public void airplaneModeToggleOffIsDeferredWhileProcessingToggleOnWithTwoModeManager() 4353 throws Exception { 4354 enterClientModeActiveState(); 4355 enterSoftApActiveMode(); 4356 assertInEnabledState(); 4357 4358 // APM toggle on 4359 assertWifiShutDown(() -> { 4360 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 4361 mActiveModeWarden.airplaneModeToggled(); 4362 mLooper.dispatchAll(); 4363 }); 4364 4365 4366 // APM toggle off before the stop is complete. 4367 assertInEnabledState(); 4368 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 4369 mActiveModeWarden.airplaneModeToggled(); 4370 mLooper.dispatchAll(); 4371 4372 // AP stopped, should not process APM toggle. 4373 mSoftApListener.onStopped(mSoftApManager); 4374 mLooper.dispatchAll(); 4375 verify(mWifiInjector, times(1)).makeClientModeManager( 4376 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 4377 4378 // STA also stopped, should process APM toggle. 4379 mClientListener.onStopped(mClientModeManager); 4380 mLooper.dispatchAll(); 4381 verify(mWifiInjector, times(2)).makeClientModeManager( 4382 any(), any(), eq(ROLE_CLIENT_PRIMARY), anyBoolean()); 4383 4384 mClientListener.onStarted(mClientModeManager); 4385 mLooper.dispatchAll(); 4386 4387 // We should be back to enabled state. 4388 assertInEnabledState(); 4389 } 4390 4391 @Test propagateVerboseLoggingFlagToClientModeManager()4392 public void propagateVerboseLoggingFlagToClientModeManager() throws Exception { 4393 mActiveModeWarden.enableVerboseLogging(true); 4394 enterClientModeActiveState(); 4395 assertInEnabledState(); 4396 verify(mWifiInjector).makeClientModeManager(any(), any(), any(), eq(true)); 4397 4398 mActiveModeWarden.enableVerboseLogging(false); 4399 verify(mClientModeManager).enableVerboseLogging(false); 4400 } 4401 4402 @Test propagateConnectedWifiScorerToPrimaryClientModeManager()4403 public void propagateConnectedWifiScorerToPrimaryClientModeManager() throws Exception { 4404 IBinder iBinder = mock(IBinder.class); 4405 IWifiConnectedNetworkScorer iScorer = mock(IWifiConnectedNetworkScorer.class); 4406 mActiveModeWarden.setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4407 verify(iScorer).onSetScoreUpdateObserver(mExternalScoreUpdateObserverProxy); 4408 enterClientModeActiveState(); 4409 assertInEnabledState(); 4410 verify(mClientModeManager).setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4411 4412 mActiveModeWarden.clearWifiConnectedNetworkScorer(); 4413 verify(mClientModeManager).clearWifiConnectedNetworkScorer(); 4414 4415 mActiveModeWarden.setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4416 verify(mClientModeManager, times(2)).setWifiConnectedNetworkScorer(iBinder, iScorer, 4417 TEST_UID); 4418 } 4419 4420 @Test propagateConnectedWifiScorerToPrimaryClientModeManager_enterScanOnlyState()4421 public void propagateConnectedWifiScorerToPrimaryClientModeManager_enterScanOnlyState() 4422 throws Exception { 4423 IBinder iBinder = mock(IBinder.class); 4424 IWifiConnectedNetworkScorer iScorer = mock(IWifiConnectedNetworkScorer.class); 4425 mActiveModeWarden.setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4426 verify(iScorer).onSetScoreUpdateObserver(mExternalScoreUpdateObserverProxy); 4427 enterClientModeActiveState(); 4428 assertInEnabledState(); 4429 verify(mClientModeManager).setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4430 4431 enterScanOnlyModeActiveState(true); 4432 4433 verify(mClientModeManager).clearWifiConnectedNetworkScorer(); 4434 } 4435 4436 @Test handleWifiScorerSetScoreUpdateObserverFailure()4437 public void handleWifiScorerSetScoreUpdateObserverFailure() throws Exception { 4438 IBinder iBinder = mock(IBinder.class); 4439 IWifiConnectedNetworkScorer iScorer = mock(IWifiConnectedNetworkScorer.class); 4440 doThrow(new RemoteException()).when(iScorer).onSetScoreUpdateObserver(any()); 4441 mActiveModeWarden.setWifiConnectedNetworkScorer(iBinder, iScorer, TEST_UID); 4442 verify(iScorer).onSetScoreUpdateObserver(mExternalScoreUpdateObserverProxy); 4443 enterClientModeActiveState(); 4444 assertInEnabledState(); 4445 // Ensure we did not propagate the scorer. 4446 verify(mClientModeManager, never()).setWifiConnectedNetworkScorer(iBinder, iScorer, 4447 TEST_UID); 4448 } 4449 4450 /** Verify that the primary changed callback is triggered when entering client mode. */ 4451 @Test testAddPrimaryClientModeManager()4452 public void testAddPrimaryClientModeManager() throws Exception { 4453 enterClientModeActiveState(); 4454 4455 verify(mPrimaryChangedCallback).onChange(null, mClientModeManager); 4456 } 4457 4458 /** Verify the primary changed callback is not triggered when there is no primary. */ 4459 @Test testNoAddPrimaryClientModeManager()4460 public void testNoAddPrimaryClientModeManager() throws Exception { 4461 enterScanOnlyModeActiveState(); 4462 4463 verify(mPrimaryChangedCallback, never()).onChange(any(), any()); 4464 } 4465 4466 /** 4467 * Verify the primary changed callback is triggered when changing the primary from one 4468 * ClientModeManager to another. 4469 */ 4470 @Test testSwitchPrimaryClientModeManager()4471 public void testSwitchPrimaryClientModeManager() throws Exception { 4472 // Ensure that we can create more client ifaces. 4473 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4474 when(mWifiResourceCache.getBoolean( 4475 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 4476 .thenReturn(true); 4477 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4478 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false)); 4479 4480 enterClientModeActiveState(); 4481 4482 verify(mPrimaryChangedCallback).onChange(null, mClientModeManager); 4483 4484 // Connected to ssid1/bssid1 4485 WifiConfiguration config1 = new WifiConfiguration(); 4486 config1.SSID = TEST_SSID_1; 4487 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 4488 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 4489 4490 ConcreteClientModeManager additionalClientModeManager = 4491 mock(ConcreteClientModeManager.class); 4492 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4493 new Mutable<>(); 4494 doAnswer((invocation) -> { 4495 Object[] args = invocation.getArguments(); 4496 additionalClientListener.value = 4497 (Listener<ConcreteClientModeManager>) args[0]; 4498 return additionalClientModeManager; 4499 }).when(mWifiInjector).makeClientModeManager( 4500 any(Listener.class), any(), eq(ROLE_CLIENT_SECONDARY_TRANSIENT), 4501 anyBoolean()); 4502 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4503 4504 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4505 ExternalClientModeManagerRequestListener.class); 4506 // request for ssid2/bssid2 4507 mActiveModeWarden.requestSecondaryTransientClientModeManager( 4508 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4509 mLooper.dispatchAll(); 4510 verify(mWifiInjector).makeClientModeManager( 4511 any(), eq(TEST_WORKSOURCE), eq(ROLE_CLIENT_SECONDARY_TRANSIENT), anyBoolean()); 4512 additionalClientListener.value.onStarted(additionalClientModeManager); 4513 mLooper.dispatchAll(); 4514 // Returns the new client mode manager. 4515 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4516 ArgumentCaptor.forClass(ClientModeManager.class); 4517 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4518 assertEquals(additionalClientModeManager, requestedClientModeManager.getValue()); 4519 4520 // primary didn't change yet 4521 verify(mPrimaryChangedCallback, never()).onChange(any(), eq(additionalClientModeManager)); 4522 4523 // change primary 4524 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4525 mClientListener.onRoleChanged(mClientModeManager); 4526 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 4527 additionalClientListener.value.onRoleChanged(additionalClientModeManager); 4528 4529 // verify callback triggered 4530 verify(mPrimaryChangedCallback).onChange(mClientModeManager, null); 4531 verify(mPrimaryChangedCallback).onChange(null, additionalClientModeManager); 4532 } 4533 4534 @Test testRegisterPrimaryCmmChangedCallbackWhenConnectModeActiveState()4535 public void testRegisterPrimaryCmmChangedCallbackWhenConnectModeActiveState() throws Exception { 4536 enterClientModeActiveState(); 4537 4538 // register a new primary cmm change callback. 4539 ActiveModeWarden.PrimaryClientModeManagerChangedCallback primarCmmCallback = mock( 4540 ActiveModeWarden.PrimaryClientModeManagerChangedCallback.class); 4541 mActiveModeWarden.registerPrimaryClientModeManagerChangedCallback(primarCmmCallback); 4542 // Ensure we get the callback immediately. 4543 verify(primarCmmCallback).onChange(null, mClientModeManager); 4544 } 4545 4546 @Test testGetCmmInRolesWithNullRoleInOneCmm()4547 public void testGetCmmInRolesWithNullRoleInOneCmm() throws Exception { 4548 enterClientModeActiveState(); 4549 4550 // Ensure that we can create more client ifaces. 4551 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4552 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 4553 .thenReturn(true); 4554 4555 ConcreteClientModeManager additionalClientModeManager = 4556 mock(ConcreteClientModeManager.class); 4557 when(mWifiInjector.makeClientModeManager( 4558 any(), any(), any(), anyBoolean())).thenReturn(additionalClientModeManager); 4559 4560 mActiveModeWarden.requestLocalOnlyClientModeManager( 4561 mock(ExternalClientModeManagerRequestListener.class), 4562 TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, false); 4563 mLooper.dispatchAll(); 4564 4565 // No role set, should be ignored. 4566 when(additionalClientModeManager.getRole()).thenReturn(null); 4567 assertEquals(1, mActiveModeWarden.getClientModeManagersInRoles( 4568 ROLE_CLIENT_PRIMARY, ROLE_CLIENT_LOCAL_ONLY).size()); 4569 4570 // Role set, should be included. 4571 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 4572 assertEquals(2, mActiveModeWarden.getClientModeManagersInRoles( 4573 ROLE_CLIENT_PRIMARY, ROLE_CLIENT_LOCAL_ONLY).size()); 4574 } 4575 4576 /** 4577 * Helper method to enter the EnabledState and set ClientModeManager in ScanOnlyMode during 4578 * emergency scan processing. 4579 */ indicateStartOfEmergencyScan( boolean hasAnyOtherStaToggleEnabled, @Nullable ActiveModeManager.ClientRole expectedRole)4580 private void indicateStartOfEmergencyScan( 4581 boolean hasAnyOtherStaToggleEnabled, 4582 @Nullable ActiveModeManager.ClientRole expectedRole) 4583 throws Exception { 4584 String fromState = mActiveModeWarden.getCurrentMode(); 4585 mActiveModeWarden.setEmergencyScanRequestInProgress(true); 4586 mLooper.dispatchAll(); 4587 4588 if (!hasAnyOtherStaToggleEnabled) { 4589 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY); 4590 mClientListener.onStarted(mClientModeManager); 4591 mLooper.dispatchAll(); 4592 verify(mWifiInjector).makeClientModeManager( 4593 any(), eq(SETTINGS_WORKSOURCE), eq(ROLE_CLIENT_SCAN_ONLY), anyBoolean()); 4594 verify(mModeChangeCallback).onActiveModeManagerAdded(mClientModeManager); 4595 verify(mScanRequestProxy).enableScanning(true, false); 4596 verify(mBatteryStats).reportWifiOn(); 4597 verify(mBatteryStats).reportWifiState( 4598 BatteryStatsManager.WIFI_STATE_OFF_SCANNING, null); 4599 } else { 4600 verify(mClientModeManager).setRole(eq(expectedRole), any()); 4601 verify(mClientModeManager, never()).stop(); 4602 assertEquals(fromState, mActiveModeWarden.getCurrentMode()); 4603 } 4604 assertInEnabledState(); 4605 } 4606 indicateEndOfEmergencyScan( boolean hasAnyOtherStaToggleEnabled, @Nullable ActiveModeManager.ClientRole expectedRole)4607 private void indicateEndOfEmergencyScan( 4608 boolean hasAnyOtherStaToggleEnabled, 4609 @Nullable ActiveModeManager.ClientRole expectedRole) { 4610 String fromState = mActiveModeWarden.getCurrentMode(); 4611 mActiveModeWarden.setEmergencyScanRequestInProgress(false); 4612 mLooper.dispatchAll(); 4613 if (!hasAnyOtherStaToggleEnabled) { 4614 mClientListener.onStopped(mClientModeManager); 4615 mLooper.dispatchAll(); 4616 verify(mModeChangeCallback).onActiveModeManagerRemoved(mClientModeManager); 4617 verify(mScanRequestProxy).enableScanning(false, false); 4618 assertInDisabledState(); 4619 } else { 4620 // Nothing changes. 4621 verify(mClientModeManager).setRole(eq(expectedRole), any()); 4622 verify(mClientModeManager, never()).stop(); 4623 assertEquals(fromState, mActiveModeWarden.getCurrentMode()); 4624 } 4625 } 4626 4627 @Test testEmergencyScanWhenWifiDisabled()4628 public void testEmergencyScanWhenWifiDisabled() throws Exception { 4629 // Wifi fully disabled. 4630 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 4631 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 4632 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 4633 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 4634 4635 indicateStartOfEmergencyScan(false, null); 4636 4637 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4638 clearInvocations(mClientModeManager); 4639 4640 indicateEndOfEmergencyScan(false, null); 4641 } 4642 4643 @Test testEmergencyScanWhenWifiEnabled()4644 public void testEmergencyScanWhenWifiEnabled() throws Exception { 4645 // Wifi enabled. 4646 enterClientModeActiveState(); 4647 4648 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4649 4650 indicateStartOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4651 4652 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4653 clearInvocations(mClientModeManager); 4654 4655 indicateEndOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4656 } 4657 4658 @Test testEmergencyScanWhenScanOnlyModeEnabled()4659 public void testEmergencyScanWhenScanOnlyModeEnabled() throws Exception { 4660 // Scan only enabled. 4661 enterScanOnlyModeActiveState(); 4662 4663 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4664 4665 indicateStartOfEmergencyScan(true, ROLE_CLIENT_SCAN_ONLY); 4666 4667 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4668 clearInvocations(mClientModeManager); 4669 4670 indicateEndOfEmergencyScan(true, ROLE_CLIENT_SCAN_ONLY); 4671 } 4672 4673 @Test testEmergencyScanWhenEcmOnWithWifiDisableInEcbm()4674 public void testEmergencyScanWhenEcmOnWithWifiDisableInEcbm() throws Exception { 4675 // Wifi enabled. 4676 enterClientModeActiveState(); 4677 4678 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4679 4680 // Test with WifiDisableInECBM turned on 4681 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 4682 4683 assertWifiShutDown(() -> { 4684 // test ecm changed 4685 emergencyCallbackModeChanged(true); 4686 mLooper.dispatchAll(); 4687 // fully shutdown 4688 mClientListener.onStopped(mClientModeManager); 4689 mLooper.dispatchAll(); 4690 }); 4691 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4692 4693 indicateStartOfEmergencyScan(false, null); 4694 4695 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4696 clearInvocations(mClientModeManager); 4697 4698 indicateEndOfEmergencyScan(false, null); 4699 } 4700 4701 @Test testEmergencyScanWhenEcmOnWithoutWifiDisableInEcbm()4702 public void testEmergencyScanWhenEcmOnWithoutWifiDisableInEcbm() throws Exception { 4703 // Wifi enabled. 4704 enterClientModeActiveState(); 4705 4706 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4707 4708 // Test with WifiDisableInECBM turned off 4709 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 4710 4711 assertEnteredEcmMode(() -> { 4712 // test ecm changed 4713 emergencyCallbackModeChanged(true); 4714 mLooper.dispatchAll(); 4715 }); 4716 4717 indicateStartOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4718 4719 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4720 clearInvocations(mClientModeManager); 4721 4722 indicateEndOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4723 } 4724 4725 @Test testWifiDisableDuringEmergencyScan()4726 public void testWifiDisableDuringEmergencyScan() throws Exception { 4727 // Wifi enabled. 4728 enterClientModeActiveState(); 4729 4730 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4731 4732 indicateStartOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4733 4734 // Toggle off wifi 4735 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 4736 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 4737 mLooper.dispatchAll(); 4738 4739 // Ensure that we switched the role to scan only state because of the emergency scan. 4740 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY); 4741 mClientListener.onRoleChanged(mClientModeManager); 4742 mLooper.dispatchAll(); 4743 verify(mClientModeManager).setRole(ROLE_CLIENT_SCAN_ONLY, INTERNAL_REQUESTOR_WS); 4744 verify(mClientModeManager, never()).stop(); 4745 assertInEnabledState(); 4746 4747 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4748 clearInvocations(mClientModeManager); 4749 4750 indicateEndOfEmergencyScan(false, null); 4751 } 4752 4753 @Test testScanOnlyModeDisableDuringEmergencyScan()4754 public void testScanOnlyModeDisableDuringEmergencyScan() throws Exception { 4755 // Scan only enabled. 4756 enterScanOnlyModeActiveState(); 4757 4758 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4759 4760 indicateStartOfEmergencyScan(true, ROLE_CLIENT_SCAN_ONLY); 4761 4762 // To reset setRole invocation above which is checked below. 4763 clearInvocations(mClientModeManager); 4764 4765 // Toggle off scan only mode 4766 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 4767 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false); 4768 mActiveModeWarden.scanAlwaysModeChanged(); 4769 mLooper.dispatchAll(); 4770 4771 // Ensure that we remained in scan only state because of the emergency scan. 4772 verify(mClientModeManager).setRole(eq(ROLE_CLIENT_SCAN_ONLY), any()); 4773 verify(mClientModeManager, never()).stop(); 4774 assertInEnabledState(); 4775 4776 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4777 clearInvocations(mClientModeManager); 4778 4779 indicateEndOfEmergencyScan(false, null); 4780 } 4781 4782 @Test testEcmOffWithWifiDisabledStateDuringEmergencyScan()4783 public void testEcmOffWithWifiDisabledStateDuringEmergencyScan() throws Exception { 4784 // Wifi enabled. 4785 enterClientModeActiveState(); 4786 4787 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4788 4789 // Test with WifiDisableInECBM turned on 4790 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true); 4791 4792 assertWifiShutDown(() -> { 4793 // test ecm changed 4794 emergencyCallbackModeChanged(true); 4795 mLooper.dispatchAll(); 4796 // fully shutdown 4797 mClientListener.onStopped(mClientModeManager); 4798 mLooper.dispatchAll(); 4799 }); 4800 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4801 4802 indicateStartOfEmergencyScan(false, null); 4803 4804 // Now turn off ECM 4805 emergencyCallbackModeChanged(false); 4806 mLooper.dispatchAll(); 4807 4808 // Ensure we turned wifi back on. 4809 verify(mClientModeManager).setRole(eq(ROLE_CLIENT_PRIMARY), any()); 4810 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 4811 mClientListener.onRoleChanged(mClientModeManager); 4812 verify(mScanRequestProxy).enableScanning(true, true); 4813 assertInEnabledState(); 4814 4815 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4816 clearInvocations(mClientModeManager); 4817 4818 indicateEndOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4819 } 4820 4821 @Test testEcmOffWithoutWifiDisabledStateDuringEmergencyScan()4822 public void testEcmOffWithoutWifiDisabledStateDuringEmergencyScan() throws Exception { 4823 // Wifi enabled. 4824 enterClientModeActiveState(); 4825 4826 reset(mBatteryStats, mScanRequestProxy, mModeChangeCallback); 4827 4828 // Test with WifiDisableInECBM turned off 4829 when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false); 4830 4831 assertEnteredEcmMode(() -> { 4832 // test ecm changed 4833 emergencyCallbackModeChanged(true); 4834 mLooper.dispatchAll(); 4835 }); 4836 4837 // Now turn off ECM 4838 emergencyCallbackModeChanged(false); 4839 mLooper.dispatchAll(); 4840 4841 // Ensure that we remained in connected state. 4842 verify(mClientModeManager).setRole(eq(ROLE_CLIENT_PRIMARY), any()); 4843 verify(mClientModeManager, never()).stop(); 4844 assertInEnabledState(); 4845 4846 // To reset setRole invocation above which is checked inside |indicateEndOfEmergencyScan| 4847 clearInvocations(mClientModeManager); 4848 4849 indicateEndOfEmergencyScan(true, ROLE_CLIENT_PRIMARY); 4850 } 4851 4852 @Test testRequestForSecondaryLocalOnlyForPreSAppWithUserConnect()4853 public void testRequestForSecondaryLocalOnlyForPreSAppWithUserConnect() throws Exception { 4854 // Ensure that we can create more client ifaces. 4855 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4856 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 4857 .thenReturn(true); 4858 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 4859 .thenReturn(true); 4860 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 4861 when(mWifiPermissionsUtil.isTargetSdkLessThan( 4862 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 4863 .thenReturn(true); 4864 when(mWifiPermissionsUtil.isTargetSdkLessThan( 4865 "system-service", Build.VERSION_CODES.S, Process.SYSTEM_UID)) 4866 .thenReturn(false); 4867 assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4868 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, true)); 4869 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4870 TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)); 4871 4872 enterClientModeActiveState(); 4873 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4874 ArgumentCaptor.forClass(ClientModeManager.class); 4875 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4876 ExternalClientModeManagerRequestListener.class); 4877 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4878 new Mutable<>(); 4879 ConcreteClientModeManager additionalClientModeManager = 4880 mock(ConcreteClientModeManager.class); 4881 doAnswer((invocation) -> { 4882 Object[] args = invocation.getArguments(); 4883 additionalClientListener.value = 4884 (Listener<ConcreteClientModeManager>) args[0]; 4885 return additionalClientModeManager; 4886 }).when(mWifiInjector).makeClientModeManager( 4887 any(Listener.class), any(), any(), anyBoolean()); 4888 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 4889 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 4890 4891 // mock requesting local only secondary 4892 mActiveModeWarden.requestLocalOnlyClientModeManager( 4893 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, true); 4894 mLooper.dispatchAll(); 4895 // Verify the primary is given to the externalRequestListener 4896 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4897 verify(mWifiInjector, never()).makeClientModeManager( 4898 any(), any(), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 4899 assertEquals(ROLE_CLIENT_PRIMARY, requestedClientModeManager.getValue().getRole()); 4900 4901 // Request for non local-only STA and verify the secondary STA is provided instead. 4902 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 4903 mActiveModeWarden.requestSecondaryLongLivedClientModeManager( 4904 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2); 4905 mLooper.dispatchAll(); 4906 verify(mWifiInjector).makeClientModeManager(any(), any(), 4907 eq(ROLE_CLIENT_SECONDARY_LONG_LIVED), anyBoolean()); 4908 4909 additionalClientListener.value.onStarted(additionalClientModeManager); 4910 mLooper.dispatchAll(); 4911 verify(externalRequestListener, times(2)).onAnswer( 4912 requestedClientModeManager.capture()); 4913 assertEquals(ROLE_CLIENT_SECONDARY_LONG_LIVED, 4914 requestedClientModeManager.getValue().getRole()); 4915 } 4916 4917 @Test testRequestForSecondaryLocalOnlyForAppWithUserConnect()4918 public void testRequestForSecondaryLocalOnlyForAppWithUserConnect() throws Exception { 4919 // Ensure that we can create more client ifaces. 4920 when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true); 4921 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 4922 .thenReturn(true); 4923 when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false); 4924 when(mWifiPermissionsUtil.isTargetSdkLessThan( 4925 TEST_PACKAGE, Build.VERSION_CODES.S, TEST_UID)) 4926 .thenReturn(false); 4927 assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole( 4928 TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, true)); 4929 4930 enterClientModeActiveState(); 4931 ArgumentCaptor<ClientModeManager> requestedClientModeManager = 4932 ArgumentCaptor.forClass(ClientModeManager.class); 4933 ExternalClientModeManagerRequestListener externalRequestListener = mock( 4934 ExternalClientModeManagerRequestListener.class); 4935 Mutable<Listener<ConcreteClientModeManager>> additionalClientListener = 4936 new Mutable<>(); 4937 ConcreteClientModeManager additionalClientModeManager = 4938 mock(ConcreteClientModeManager.class); 4939 doAnswer((invocation) -> { 4940 Object[] args = invocation.getArguments(); 4941 additionalClientListener.value = 4942 (Listener<ConcreteClientModeManager>) args[0]; 4943 return additionalClientModeManager; 4944 }).when(mWifiInjector).makeClientModeManager( 4945 any(Listener.class), any(), any(), anyBoolean()); 4946 when(additionalClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME_1); 4947 when(additionalClientModeManager.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY); 4948 4949 // mock requesting local only secondary 4950 mActiveModeWarden.requestLocalOnlyClientModeManager( 4951 externalRequestListener, TEST_WORKSOURCE, TEST_SSID_2, TEST_BSSID_2, true); 4952 mLooper.dispatchAll(); 4953 WorkSource ws = new WorkSource(TEST_WORKSOURCE); 4954 ws.add(SETTINGS_WORKSOURCE); 4955 verify(mWifiInjector).makeClientModeManager( 4956 any(), eq(ws), eq(ROLE_CLIENT_LOCAL_ONLY), anyBoolean()); 4957 additionalClientListener.value.onStarted(additionalClientModeManager); 4958 mLooper.dispatchAll(); 4959 // Verify the primary is given to the externalRequestListener 4960 verify(externalRequestListener).onAnswer(requestedClientModeManager.capture()); 4961 4962 assertEquals(ROLE_CLIENT_LOCAL_ONLY, requestedClientModeManager.getValue().getRole()); 4963 } 4964 4965 @Test testSetAndGetWifiState()4966 public void testSetAndGetWifiState() { 4967 int invalidState = 5; 4968 mActiveModeWarden.setWifiStateForApiCalls(WIFI_STATE_ENABLED); 4969 assertEquals(WIFI_STATE_ENABLED, mActiveModeWarden.getWifiState()); 4970 mActiveModeWarden.setWifiStateForApiCalls(invalidState); 4971 assertEquals(WIFI_STATE_ENABLED, mActiveModeWarden.getWifiState()); 4972 } 4973 4974 /** 4975 * Verifies that getSupportedFeatureSet() adds capabilities based on interface 4976 * combination. 4977 */ 4978 @Test testGetSupportedFeaturesForStaApConcurrency()4979 public void testGetSupportedFeaturesForStaApConcurrency() throws Exception { 4980 enterScanOnlyModeActiveState(); 4981 BitSet supportedFeaturesFromWifiNative = 4982 createCapabilityBitset(WifiManager.WIFI_FEATURE_OWE); 4983 when(mWifiNative.getSupportedFeatureSet(null)).thenReturn(supportedFeaturesFromWifiNative); 4984 when(mWifiNative.isStaApConcurrencySupported()).thenReturn(false); 4985 mClientListener.onStarted(mClientModeManager); 4986 4987 assertTrue(supportedFeaturesFromWifiNative 4988 .equals(mActiveModeWarden.getSupportedFeatureSet())); 4989 4990 when(mWifiNative.isStaApConcurrencySupported()).thenReturn(true); 4991 mClientListener.onStarted(mClientModeManager); 4992 4993 assertTrue(addCapabilitiesToBitset( 4994 supportedFeaturesFromWifiNative, WifiManager.WIFI_FEATURE_AP_STA) 4995 .equals(mActiveModeWarden.getSupportedFeatureSet())); 4996 } 4997 4998 /** 4999 * Verifies that getSupportedFeatureSet() adds capabilities based on interface 5000 * combination. 5001 */ 5002 @Test testGetSupportedFeaturesForStaStaConcurrency()5003 public void testGetSupportedFeaturesForStaStaConcurrency() throws Exception { 5004 assumeTrue(SdkLevel.isAtLeastS()); 5005 enterScanOnlyModeActiveState(); 5006 BitSet supportedFeaturesFromWifiNative = 5007 createCapabilityBitset(WifiManager.WIFI_FEATURE_OWE); 5008 when(mWifiNative.getSupportedFeatureSet(null)).thenReturn( 5009 supportedFeaturesFromWifiNative); 5010 5011 mClientListener.onStarted(mClientModeManager); 5012 assertTrue(supportedFeaturesFromWifiNative 5013 .equals(mActiveModeWarden.getSupportedFeatureSet())); 5014 5015 when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(true); 5016 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) 5017 .thenReturn(true); 5018 mClientListener.onStarted(mClientModeManager); 5019 assertTrue(addCapabilitiesToBitset(supportedFeaturesFromWifiNative, 5020 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY) 5021 .equals(mActiveModeWarden.getSupportedFeatureSet())); 5022 5023 when(mWifiResourceCache.getBoolean( 5024 R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) 5025 .thenReturn(true); 5026 mClientListener.onStarted(mClientModeManager); 5027 assertTrue(addCapabilitiesToBitset(supportedFeaturesFromWifiNative, 5028 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY, 5029 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB) 5030 .equals(mActiveModeWarden.getSupportedFeatureSet())); 5031 5032 when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) 5033 .thenReturn(true); 5034 when(mWifiResourceCache.getBoolean( 5035 R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled)).thenReturn(true); 5036 mClientListener.onStarted(mClientModeManager); 5037 assertTrue(addCapabilitiesToBitset(supportedFeaturesFromWifiNative, 5038 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY, 5039 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB, 5040 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED, 5041 WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET) 5042 .equals(mActiveModeWarden.getSupportedFeatureSet())); 5043 } 5044 testGetSupportedFeaturesCaseForMacRandomization( BitSet supportedFeaturesFromWifiNative, boolean apMacRandomizationEnabled, boolean staConnectedMacRandomizationEnabled, boolean p2pMacRandomizationEnabled)5045 private BitSet testGetSupportedFeaturesCaseForMacRandomization( 5046 BitSet supportedFeaturesFromWifiNative, boolean apMacRandomizationEnabled, 5047 boolean staConnectedMacRandomizationEnabled, boolean p2pMacRandomizationEnabled) { 5048 when(mWifiResourceCache.getBoolean( 5049 R.bool.config_wifi_connected_mac_randomization_supported)) 5050 .thenReturn(staConnectedMacRandomizationEnabled); 5051 when(mWifiResourceCache.getBoolean( 5052 R.bool.config_wifi_ap_mac_randomization_supported)) 5053 .thenReturn(apMacRandomizationEnabled); 5054 when(mWifiResourceCache.getBoolean( 5055 R.bool.config_wifi_p2p_mac_randomization_supported)) 5056 .thenReturn(p2pMacRandomizationEnabled); 5057 when(mWifiNative.getSupportedFeatureSet(anyString())) 5058 .thenReturn(supportedFeaturesFromWifiNative); 5059 mClientListener.onStarted(mClientModeManager); 5060 mLooper.dispatchAll(); 5061 return mActiveModeWarden.getSupportedFeatureSet(); 5062 } 5063 5064 /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */ 5065 @Test syncGetSupportedFeaturesForMacRandomization()5066 public void syncGetSupportedFeaturesForMacRandomization() throws Exception { 5067 final BitSet featureStaConnectedMacRandomization = 5068 createCapabilityBitset(WifiManager.WIFI_FEATURE_CONNECTED_RAND_MAC); 5069 final BitSet featureApMacRandomization = 5070 createCapabilityBitset(WifiManager.WIFI_FEATURE_AP_RAND_MAC); 5071 final BitSet featureP2pMacRandomization = 5072 createCapabilityBitset(WifiManager.WIFI_FEATURE_CONNECTED_RAND_MAC); 5073 5074 enterClientModeActiveState(); 5075 assertTrue(combineBitsets(featureStaConnectedMacRandomization, featureApMacRandomization, 5076 featureP2pMacRandomization) 5077 .equals(testGetSupportedFeaturesCaseForMacRandomization( 5078 featureP2pMacRandomization, true, true, true))); 5079 // p2p supported by HAL, but disabled by overlay. 5080 assertTrue(combineBitsets(featureStaConnectedMacRandomization, featureApMacRandomization) 5081 .equals(testGetSupportedFeaturesCaseForMacRandomization( 5082 featureP2pMacRandomization, true, true, false))); 5083 assertTrue(combineBitsets(featureStaConnectedMacRandomization, featureApMacRandomization) 5084 .equals(testGetSupportedFeaturesCaseForMacRandomization( 5085 new BitSet(), true, true, false))); 5086 } 5087 testGetSupportedFeaturesCaseForRtt( BitSet supportedFeaturesFromWifiNative, boolean rttDisabled)5088 private BitSet testGetSupportedFeaturesCaseForRtt( 5089 BitSet supportedFeaturesFromWifiNative, boolean rttDisabled) { 5090 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn( 5091 !rttDisabled); 5092 when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn( 5093 supportedFeaturesFromWifiNative); 5094 mClientListener.onStarted(mClientModeManager); 5095 mLooper.dispatchAll(); 5096 return mActiveModeWarden.getSupportedFeatureSet(); 5097 } 5098 5099 /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */ 5100 @Test syncGetSupportedFeaturesForRtt()5101 public void syncGetSupportedFeaturesForRtt() throws Exception { 5102 final BitSet featureAware = createCapabilityBitset(WifiManager.WIFI_FEATURE_AWARE); 5103 final BitSet featureInfra = createCapabilityBitset(WifiManager.WIFI_FEATURE_INFRA); 5104 final BitSet featureD2dRtt = createCapabilityBitset(WifiManager.WIFI_FEATURE_D2D_RTT); 5105 final BitSet featureD2apRtt = createCapabilityBitset(WifiManager.WIFI_FEATURE_D2AP_RTT); 5106 5107 enterClientModeActiveState(); 5108 5109 assertTrue(testGetSupportedFeaturesCaseForRtt(new BitSet(), false).equals(new BitSet())); 5110 assertTrue(testGetSupportedFeaturesCaseForRtt(new BitSet(), true).equals(new BitSet())); 5111 assertTrue(combineBitsets(featureAware, featureInfra).equals( 5112 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureAware, featureInfra), 5113 false))); 5114 assertTrue(combineBitsets(featureAware, featureInfra).equals( 5115 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureAware, featureInfra), 5116 true))); 5117 assertTrue(combineBitsets(featureInfra, featureD2dRtt).equals( 5118 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureInfra, featureD2dRtt), 5119 false))); 5120 assertTrue(featureInfra.equals( 5121 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureInfra, featureD2dRtt), 5122 true))); 5123 assertTrue(combineBitsets(featureInfra, featureD2apRtt).equals( 5124 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureInfra, featureD2apRtt), 5125 false))); 5126 assertTrue(featureInfra.equals( 5127 testGetSupportedFeaturesCaseForRtt(combineBitsets(featureInfra, featureD2apRtt), 5128 true))); 5129 assertTrue(combineBitsets(featureInfra, featureD2dRtt, featureD2apRtt).equals( 5130 testGetSupportedFeaturesCaseForRtt( 5131 combineBitsets(featureInfra, featureD2dRtt, featureD2apRtt), 5132 false))); 5133 assertTrue(featureInfra.equals( 5134 testGetSupportedFeaturesCaseForRtt( 5135 combineBitsets(featureInfra, featureD2dRtt, featureD2apRtt), 5136 true))); 5137 } 5138 5139 @Test testGetCurrentNetworkScanOnly()5140 public void testGetCurrentNetworkScanOnly() throws Exception { 5141 enterScanOnlyModeActiveState(); 5142 assertNull(mActiveModeWarden.getCurrentNetwork()); 5143 } 5144 testGetCurrentNetworkClientMode()5145 @Test public void testGetCurrentNetworkClientMode() throws Exception { 5146 mActiveModeWarden.setCurrentNetwork(mNetwork); 5147 assertEquals(mNetwork, mActiveModeWarden.getCurrentNetwork()); 5148 } 5149 5150 /** 5151 * Verifies that isClientModeManagerConnectedOrConnectingToBssid() checks for Affiliated link 5152 * BSSID, if exists. 5153 */ 5154 @Test testClientModeManagerConnectedOrConnectingToBssid()5155 public void testClientModeManagerConnectedOrConnectingToBssid() { 5156 5157 WifiConfiguration config1 = new WifiConfiguration(); 5158 config1.SSID = TEST_SSID_1; 5159 MacAddress bssid2 = MacAddress.fromString(TEST_BSSID_2); 5160 when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1); 5161 when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1); 5162 when(mClientModeManager.isAffiliatedLinkBssid(eq(bssid2))).thenReturn(true); 5163 5164 assertTrue(mActiveModeWarden.isClientModeManagerConnectedOrConnectingToBssid( 5165 mClientModeManager, TEST_SSID_1, TEST_BSSID_2)); 5166 } 5167 5168 @Test syncGetSupportedBands()5169 public void syncGetSupportedBands() throws Exception { 5170 enterClientModeActiveState(); 5171 when(mWifiNative.getSupportedBandsForSta(anyString())).thenReturn(11); 5172 mClientListener.onStarted(mClientModeManager); 5173 mLooper.dispatchAll(); 5174 verify(mSettingsConfigStore).put(WIFI_NATIVE_SUPPORTED_STA_BANDS, 11); 5175 assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ)); 5176 assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ)); 5177 assertFalse(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY)); 5178 assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ)); 5179 } 5180 5181 @Test testSatelliteModeOnDisableWifi()5182 public void testSatelliteModeOnDisableWifi() throws Exception { 5183 // Wifi is enabled 5184 enterClientModeActiveState(); 5185 assertInEnabledState(); 5186 5187 // Satellite mode is ON, disable Wifi 5188 assertWifiShutDown(() -> { 5189 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5190 mActiveModeWarden.handleSatelliteModeChange(); 5191 mLooper.dispatchAll(); 5192 }); 5193 mClientListener.onStopped(mClientModeManager); 5194 mLooper.dispatchAll(); 5195 assertInDisabledState(); 5196 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), 5197 anyInt(), anyInt(), any(), eq(false)); 5198 } 5199 5200 @Test testSatelliteModeOffNoOp()5201 public void testSatelliteModeOffNoOp() throws Exception { 5202 // Wifi is enabled 5203 enterClientModeActiveState(); 5204 assertInEnabledState(); 5205 5206 // Satellite mode is off 5207 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5208 mActiveModeWarden.handleSatelliteModeChange(); 5209 5210 mLooper.dispatchAll(); 5211 assertInEnabledState(); 5212 // Should not enable wifi again since wifi is already on 5213 verify(mLastCallerInfoManager, never()).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), 5214 anyInt(), anyInt(), any(), eq(true)); 5215 } 5216 5217 @Test testSatelliteModeOnAndThenOffEnableWifi()5218 public void testSatelliteModeOnAndThenOffEnableWifi() throws Exception { 5219 // Wifi is enabled 5220 enterClientModeActiveState(); 5221 assertInEnabledState(); 5222 5223 // Satellite mode is ON, disable Wifi 5224 assertWifiShutDown(() -> { 5225 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5226 mActiveModeWarden.handleSatelliteModeChange(); 5227 mLooper.dispatchAll(); 5228 }); 5229 mClientListener.onStopped(mClientModeManager); 5230 mLooper.dispatchAll(); 5231 assertInDisabledState(); 5232 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), 5233 anyInt(), anyInt(), any(), eq(false)); 5234 5235 // Satellite mode is off, enable Wifi 5236 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5237 mActiveModeWarden.handleSatelliteModeChange(); 5238 mLooper.dispatchAll(); 5239 assertInEnabledState(); 5240 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), 5241 anyInt(), anyInt(), any(), eq(true)); 5242 } 5243 5244 5245 @Test testSatelliteModeOnAirplaneModeOn()5246 public void testSatelliteModeOnAirplaneModeOn() throws Exception { 5247 // Sequence: Satellite ON -> APM ON -> Satellite OFF -> APM OFF 5248 5249 // Wifi is enabled 5250 enterClientModeActiveState(); 5251 assertInEnabledState(); 5252 5253 // Satellite mode is ON, disable Wifi 5254 assertWifiShutDown(() -> { 5255 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5256 mActiveModeWarden.handleSatelliteModeChange(); 5257 mLooper.dispatchAll(); 5258 }); 5259 mClientListener.onStopped(mClientModeManager); 5260 mLooper.dispatchAll(); 5261 assertInDisabledState(); 5262 5263 // APM toggle on, no change to Wifi state 5264 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 5265 mActiveModeWarden.airplaneModeToggled(); 5266 mLooper.dispatchAll(); 5267 assertInDisabledState(); 5268 5269 // Satellite mode is off, no change to Wifi state as APM is on 5270 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5271 mActiveModeWarden.handleSatelliteModeChange(); 5272 mLooper.dispatchAll(); 5273 assertInDisabledState(); 5274 5275 // APM toggle off, enable Wifi 5276 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 5277 mActiveModeWarden.airplaneModeToggled(); 5278 mLooper.dispatchAll(); 5279 assertInEnabledState(); 5280 } 5281 5282 @Test testAirplaneModeOnSatelliteModeOn()5283 public void testAirplaneModeOnSatelliteModeOn() throws Exception { 5284 // Sequence: APM ON -> Satellite ON -> APM OFF -> Satellite OFF 5285 5286 // Wifi is enabled 5287 enterClientModeActiveState(); 5288 assertInEnabledState(); 5289 5290 // APM toggle on, Wifi disabled 5291 assertWifiShutDown(() -> { 5292 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 5293 mActiveModeWarden.airplaneModeToggled(); 5294 mLooper.dispatchAll(); 5295 }); 5296 mClientListener.onStopped(mClientModeManager); 5297 mLooper.dispatchAll(); 5298 assertInDisabledState(); 5299 5300 // Satellite mode is on, no change to Wifi state 5301 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5302 mActiveModeWarden.handleSatelliteModeChange(); 5303 mLooper.dispatchAll(); 5304 assertInDisabledState(); 5305 5306 // APM toggle off, no change to Wifi state 5307 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 5308 mActiveModeWarden.airplaneModeToggled(); 5309 mLooper.dispatchAll(); 5310 assertInDisabledState(); 5311 5312 // Satellite mode is off, enable Wifi 5313 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5314 mActiveModeWarden.handleSatelliteModeChange(); 5315 mLooper.dispatchAll(); 5316 assertInEnabledState(); 5317 } 5318 5319 @Test testToggleSatelliteModeBeforeAirplaneMode()5320 public void testToggleSatelliteModeBeforeAirplaneMode() throws Exception { 5321 // Sequence: APM ON -> Satellite ON -> Satellite OFF -> APM OFF 5322 5323 // Wifi is enabled 5324 enterClientModeActiveState(); 5325 assertInEnabledState(); 5326 5327 // APM toggle on, Wifi disabled 5328 assertWifiShutDown(() -> { 5329 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 5330 mActiveModeWarden.airplaneModeToggled(); 5331 mLooper.dispatchAll(); 5332 }); 5333 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), anyInt(), 5334 anyInt(), eq("android_apm"), eq(false)); 5335 verify(mLastCallerInfoManager, never()).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), 5336 anyInt(), anyInt(), eq("android_apm"), eq(true)); 5337 mClientListener.onStopped(mClientModeManager); 5338 mLooper.dispatchAll(); 5339 assertInDisabledState(); 5340 5341 // Satellite mode is on, no change to Wifi state 5342 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5343 mActiveModeWarden.handleSatelliteModeChange(); 5344 mLooper.dispatchAll(); 5345 assertInDisabledState(); 5346 5347 // Satellite mode is off, no change to Wifi state 5348 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5349 mActiveModeWarden.handleSatelliteModeChange(); 5350 mLooper.dispatchAll(); 5351 assertInDisabledState(); 5352 5353 // APM toggle off, enable Wifi 5354 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 5355 mActiveModeWarden.airplaneModeToggled(); 5356 mLooper.dispatchAll(); 5357 assertInEnabledState(); 5358 verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(), anyInt(), 5359 anyInt(), eq("android_apm"), eq(true)); 5360 } 5361 5362 @Test testToggleAirplaneModeBeforeSatelliteMode()5363 public void testToggleAirplaneModeBeforeSatelliteMode() throws Exception { 5364 // Sequence: Satellite ON -> APM ON -> APM OFF -> Satellite OFF 5365 5366 // Wifi is enabled 5367 enterClientModeActiveState(); 5368 assertInEnabledState(); 5369 5370 // Satellite mode is ON, disable Wifi 5371 assertWifiShutDown(() -> { 5372 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5373 mActiveModeWarden.handleSatelliteModeChange(); 5374 mLooper.dispatchAll(); 5375 }); 5376 mClientListener.onStopped(mClientModeManager); 5377 mLooper.dispatchAll(); 5378 assertInDisabledState(); 5379 5380 // APM toggle on, no change to Wifi state 5381 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 5382 mActiveModeWarden.airplaneModeToggled(); 5383 mLooper.dispatchAll(); 5384 assertInDisabledState(); 5385 5386 // APM toggle off, no change to Wifi state 5387 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 5388 mActiveModeWarden.airplaneModeToggled(); 5389 mLooper.dispatchAll(); 5390 assertInDisabledState(); 5391 5392 // Satellite mode is off, enable Wifi 5393 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5394 mActiveModeWarden.handleSatelliteModeChange(); 5395 mLooper.dispatchAll(); 5396 assertInEnabledState(); 5397 } 5398 5399 @Test testToggleWifiWithSatelliteAndAirplaneMode()5400 public void testToggleWifiWithSatelliteAndAirplaneMode() throws Exception { 5401 // Sequence: APM ON -> Wifi ON -> Satellite ON -> APM OFF -> Satellite OFF 5402 5403 // Wifi is enabled 5404 enterClientModeActiveState(); 5405 assertInEnabledState(); 5406 5407 // APM toggle on, Wifi disabled 5408 assertWifiShutDown(() -> { 5409 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 5410 mActiveModeWarden.airplaneModeToggled(); 5411 mLooper.dispatchAll(); 5412 }); 5413 mClientListener.onStopped(mClientModeManager); 5414 mLooper.dispatchAll(); 5415 assertInDisabledState(); 5416 5417 // Wifi on 5418 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 5419 mActiveModeWarden.wifiToggled(TEST_WORKSOURCE); 5420 mLooper.dispatchAll(); 5421 assertInEnabledState(); 5422 5423 // Satellite mode is ON, disable Wifi 5424 assertWifiShutDown(() -> { 5425 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5426 mActiveModeWarden.handleSatelliteModeChange(); 5427 mLooper.dispatchAll(); 5428 }); 5429 mClientListener.onStopped(mClientModeManager); 5430 mLooper.dispatchAll(); 5431 assertInDisabledState(); 5432 5433 // APM toggle off, no change to Wifi state 5434 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 5435 mActiveModeWarden.airplaneModeToggled(); 5436 mLooper.dispatchAll(); 5437 assertInDisabledState(); 5438 5439 // Satellite mode is off, enable Wifi 5440 when(mSettingsStore.isSatelliteModeOn()).thenReturn(false); 5441 mActiveModeWarden.handleSatelliteModeChange(); 5442 mLooper.dispatchAll(); 5443 assertInEnabledState(); 5444 } 5445 5446 @Test testSatelliteModemDisableWifiWhenLocationModeChanged()5447 public void testSatelliteModemDisableWifiWhenLocationModeChanged() throws Exception { 5448 when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true); 5449 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false); 5450 5451 // Wifi is enabled 5452 enterClientModeActiveState(); 5453 assertInEnabledState(); 5454 5455 // Satellite mode is ON, disable Wifi 5456 assertWifiShutDown(() -> { 5457 when(mSettingsStore.isSatelliteModeOn()).thenReturn(true); 5458 mActiveModeWarden.handleSatelliteModeChange(); 5459 mLooper.dispatchAll(); 5460 }); 5461 mClientListener.onStopped(mClientModeManager); 5462 mLooper.dispatchAll(); 5463 assertInDisabledState(); 5464 5465 // Location state changes 5466 ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = 5467 ArgumentCaptor.forClass(BroadcastReceiver.class); 5468 verify(mContext).registerReceiverForAllUsers( 5469 bcastRxCaptor.capture(), 5470 argThat(filter -> filter.hasAction(LocationManager.MODE_CHANGED_ACTION)), 5471 eq(null), any(Handler.class)); 5472 BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue(); 5473 5474 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 5475 Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION); 5476 broadcastReceiver.onReceive(mContext, intent); 5477 mLooper.dispatchAll(); 5478 5479 // Ensure Wi-Fi is still disabled 5480 assertInDisabledState(); 5481 } 5482 5483 @Test testOnIdleModeChanged()5484 public void testOnIdleModeChanged() throws Exception { 5485 enterClientModeActiveState(); 5486 List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers(); 5487 assertTrue(currentCMMs.size() >= 1); 5488 mActiveModeWarden.onIdleModeChanged(true); 5489 for (ClientModeManager cmm : currentCMMs) { 5490 verify(cmm).onIdleModeChanged(true); 5491 } 5492 } 5493 5494 @Test testWepNotDeprecated()5495 public void testWepNotDeprecated() throws Exception { 5496 when(mWifiGlobals.isWepSupported()).thenReturn(true); 5497 BitSet featureSet = 5498 addCapabilitiesToBitset(TEST_FEATURE_SET, WifiManager.WIFI_FEATURE_WEP); 5499 enterClientModeActiveState(false, featureSet); 5500 } 5501 5502 @Test testWpaPersonalNotDeprecated()5503 public void testWpaPersonalNotDeprecated() throws Exception { 5504 when(mWifiGlobals.isWpaPersonalDeprecated()).thenReturn(false); 5505 BitSet featureSet = 5506 addCapabilitiesToBitset(TEST_FEATURE_SET, WifiManager.WIFI_FEATURE_WPA_PERSONAL); 5507 enterClientModeActiveState(false, featureSet); 5508 } 5509 5510 @Test testD2dSupportedWhenInfraStaDisabledWhenP2pStaConcurrencySupported()5511 public void testD2dSupportedWhenInfraStaDisabledWhenP2pStaConcurrencySupported() 5512 throws Exception { 5513 when(mWifiNative.isP2pStaConcurrencySupported()).thenReturn(true); 5514 when(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()).thenReturn(true); 5515 mActiveModeWarden = createActiveModeWarden(); 5516 mActiveModeWarden.start(); 5517 mLooper.dispatchAll(); 5518 verify(mWifiGlobals).setD2dStaConcurrencySupported(true); 5519 verify(mWifiGlobals, atLeastOnce()).isD2dSupportedWhenInfraStaDisabled(); 5520 } 5521 5522 @Test testD2dSupportedWhenInfraStaDisabledWhenNanStaConcurrencySupported()5523 public void testD2dSupportedWhenInfraStaDisabledWhenNanStaConcurrencySupported() 5524 throws Exception { 5525 when(mWifiNative.isNanStaConcurrencySupported()).thenReturn(true); 5526 when(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()).thenReturn(true); 5527 mActiveModeWarden = createActiveModeWarden(); 5528 mActiveModeWarden.start(); 5529 mLooper.dispatchAll(); 5530 verify(mWifiGlobals).setD2dStaConcurrencySupported(true); 5531 verify(mWifiGlobals, atLeastOnce()).isD2dSupportedWhenInfraStaDisabled(); 5532 } 5533 5534 @Test testGetNumberOf11beSoftApManager()5535 public void testGetNumberOf11beSoftApManager() throws Exception { 5536 assumeTrue(SdkLevel.isAtLeastT()); 5537 enterSoftApActiveMode(); 5538 when(mSoftApManager.isStarted()).thenReturn(true); 5539 SoftApModeConfiguration mockSoftApModeConfiguration = mock(SoftApModeConfiguration.class); 5540 SoftApConfiguration mockSoftApConfiguration = mock(SoftApConfiguration.class); 5541 when(mockSoftApConfiguration.isIeee80211beEnabled()).thenReturn(true); 5542 when(mockSoftApModeConfiguration.getSoftApConfiguration()) 5543 .thenReturn(mockSoftApConfiguration); 5544 when(mSoftApManager.getSoftApModeConfiguration()).thenReturn(mockSoftApModeConfiguration); 5545 assertEquals(1, mActiveModeWarden.getCurrentMLDAp()); 5546 when(mSoftApManager.isBridgedMode()).thenReturn(true); 5547 when(mSoftApManager.isUsingMlo()).thenReturn(false); 5548 assertEquals(2, mActiveModeWarden.getCurrentMLDAp()); 5549 when(mSoftApManager.isUsingMlo()).thenReturn(true); 5550 assertEquals(1, mActiveModeWarden.getCurrentMLDAp()); 5551 when(mockSoftApConfiguration.isIeee80211beEnabled()).thenReturn(false); 5552 assertEquals(0, mActiveModeWarden.getCurrentMLDAp()); 5553 } 5554 5555 /** 5556 * Verifies that registered remote WifiStateChangedListeners are notified when the Wifi state 5557 * changes. 5558 */ 5559 @Test testRegisteredWifiStateChangedListenerIsNotifiedWhenWifiStateChanges()5560 public void testRegisteredWifiStateChangedListenerIsNotifiedWhenWifiStateChanges() 5561 throws RemoteException { 5562 // Start off ENABLED 5563 mActiveModeWarden.setWifiStateForApiCalls(WIFI_STATE_ENABLED); 5564 5565 // Registering should give the current state of ENABLED. 5566 IWifiStateChangedListener remoteCallback1 = mock(IWifiStateChangedListener.class); 5567 when(remoteCallback1.asBinder()).thenReturn(mock(IBinder.class)); 5568 IWifiStateChangedListener remoteCallback2 = mock(IWifiStateChangedListener.class); 5569 when(remoteCallback2.asBinder()).thenReturn(mock(IBinder.class)); 5570 mActiveModeWarden.addWifiStateChangedListener(remoteCallback1); 5571 mActiveModeWarden.addWifiStateChangedListener(remoteCallback2); 5572 5573 // Change the state to DISABLED and verify the listeners were called. 5574 final int newState = WIFI_STATE_DISABLED; 5575 mActiveModeWarden.setWifiStateForApiCalls(newState); 5576 5577 verify(remoteCallback1, times(1)).onWifiStateChanged(); 5578 verify(remoteCallback2, times(1)).onWifiStateChanged(); 5579 5580 // Duplicate wifi state should not notify the callbacks again. 5581 mActiveModeWarden.setWifiStateForApiCalls(newState); 5582 mActiveModeWarden.setWifiStateForApiCalls(newState); 5583 mActiveModeWarden.setWifiStateForApiCalls(newState); 5584 5585 verify(remoteCallback1, times(1)).onWifiStateChanged(); 5586 verify(remoteCallback2, times(1)).onWifiStateChanged(); 5587 } 5588 5589 /** 5590 * Verifies that unregistered remote WifiStateChangedListeners are not notified when the Wifi 5591 * state changes. 5592 */ 5593 @Test testUnregisteredWifiStateChangedListenerIsNotNotifiedWhenWifiStateChanges()5594 public void testUnregisteredWifiStateChangedListenerIsNotNotifiedWhenWifiStateChanges() 5595 throws RemoteException { 5596 IWifiStateChangedListener remoteCallback1 = mock(IWifiStateChangedListener.class); 5597 when(remoteCallback1.asBinder()).thenReturn(mock(IBinder.class)); 5598 IWifiStateChangedListener remoteCallback2 = mock(IWifiStateChangedListener.class); 5599 when(remoteCallback2.asBinder()).thenReturn(mock(IBinder.class)); 5600 mActiveModeWarden.addWifiStateChangedListener(remoteCallback1); 5601 mActiveModeWarden.addWifiStateChangedListener(remoteCallback2); 5602 mActiveModeWarden.removeWifiStateChangedListener(remoteCallback1); 5603 mActiveModeWarden.removeWifiStateChangedListener(remoteCallback2); 5604 5605 final int newState = WIFI_STATE_ENABLED; 5606 mActiveModeWarden.setWifiStateForApiCalls(newState); 5607 5608 verify(remoteCallback1, never()).onWifiStateChanged(); 5609 verify(remoteCallback2, never()).onWifiStateChanged(); 5610 } 5611 } 5612