1 /* 2 * Copyright (C) 2017 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 android.net.wifi; 18 19 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; 20 import static android.net.wifi.WifiManager.ACTION_REMOVE_SUGGESTION_DISCONNECT; 21 import static android.net.wifi.WifiManager.ACTION_REMOVE_SUGGESTION_LINGER; 22 import static android.net.wifi.WifiManager.ActionListener; 23 import static android.net.wifi.WifiManager.COEX_RESTRICTION_SOFTAP; 24 import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_AWARE; 25 import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_DIRECT; 26 import static android.net.wifi.WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE; 27 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; 28 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; 29 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; 30 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED; 31 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED; 32 import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener; 33 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; 34 import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS; 35 import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; 36 import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_DISABLED; 37 import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED; 38 import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY; 39 import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY; 40 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 41 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; 42 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 43 import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY; 44 import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB; 45 import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET; 46 import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED; 47 import static android.net.wifi.WifiManager.WIFI_FEATURE_AP_STA; 48 import static android.net.wifi.WifiManager.WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED; 49 import static android.net.wifi.WifiManager.WIFI_FEATURE_DECORATED_IDENTITY; 50 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP; 51 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_AKM; 52 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_ENROLLEE_RESPONDER; 53 import static android.net.wifi.WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS; 54 import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; 55 import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P; 56 import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT; 57 import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS; 58 import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER; 59 import static android.net.wifi.WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION; 60 import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE; 61 import static android.net.wifi.WifiManager.WIFI_FEATURE_WEP; 62 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE; 63 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B; 64 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA_PERSONAL; 65 import static android.net.wifi.WifiManager.WpsCallback; 66 67 import static org.junit.Assert.assertArrayEquals; 68 import static org.junit.Assert.assertEquals; 69 import static org.junit.Assert.assertFalse; 70 import static org.junit.Assert.assertNotNull; 71 import static org.junit.Assert.assertNull; 72 import static org.junit.Assert.assertThrows; 73 import static org.junit.Assert.assertTrue; 74 import static org.junit.Assert.fail; 75 import static org.junit.Assume.assumeTrue; 76 import static org.mockito.ArgumentMatchers.anyBoolean; 77 import static org.mockito.ArgumentMatchers.nullable; 78 import static org.mockito.Mockito.any; 79 import static org.mockito.Mockito.anyInt; 80 import static org.mockito.Mockito.anyList; 81 import static org.mockito.Mockito.anyString; 82 import static org.mockito.Mockito.argThat; 83 import static org.mockito.Mockito.doThrow; 84 import static org.mockito.Mockito.eq; 85 import static org.mockito.Mockito.inOrder; 86 import static org.mockito.Mockito.mock; 87 import static org.mockito.Mockito.never; 88 import static org.mockito.Mockito.reset; 89 import static org.mockito.Mockito.spy; 90 import static org.mockito.Mockito.times; 91 import static org.mockito.Mockito.verify; 92 import static org.mockito.Mockito.verifyNoMoreInteractions; 93 import static org.mockito.Mockito.verifyZeroInteractions; 94 import static org.mockito.Mockito.when; 95 96 import android.annotation.NonNull; 97 import android.app.ActivityManager; 98 import android.content.AttributionSource; 99 import android.content.Context; 100 import android.content.pm.ApplicationInfo; 101 import android.net.DhcpInfo; 102 import android.net.DhcpOption; 103 import android.net.MacAddress; 104 import android.net.TetheringManager; 105 import android.net.wifi.WifiManager.ActiveCountryCodeChangedCallback; 106 import android.net.wifi.WifiManager.CoexCallback; 107 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback; 108 import android.net.wifi.WifiManager.LocalOnlyHotspotObserver; 109 import android.net.wifi.WifiManager.LocalOnlyHotspotReservation; 110 import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription; 111 import android.net.wifi.WifiManager.NetworkRequestMatchCallback; 112 import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; 113 import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; 114 import android.net.wifi.WifiManager.ScanResultsCallback; 115 import android.net.wifi.WifiManager.SoftApCallback; 116 import android.net.wifi.WifiManager.SubsystemRestartTrackingCallback; 117 import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; 118 import android.net.wifi.WifiManager.SuggestionUserApprovalStatusListener; 119 import android.net.wifi.WifiManager.TrafficStateCallback; 120 import android.net.wifi.WifiManager.WifiConnectedNetworkScorer; 121 import android.net.wifi.WifiUsabilityStatsEntry.ContentionTimeStats; 122 import android.net.wifi.WifiUsabilityStatsEntry.LinkStats; 123 import android.net.wifi.WifiUsabilityStatsEntry.RadioStats; 124 import android.net.wifi.WifiUsabilityStatsEntry.RateStats; 125 import android.net.wifi.twt.TwtRequest; 126 import android.net.wifi.twt.TwtSessionCallback; 127 import android.os.Build; 128 import android.os.Bundle; 129 import android.os.Handler; 130 import android.os.IBinder; 131 import android.os.RemoteException; 132 import android.os.connectivity.WifiActivityEnergyInfo; 133 import android.os.test.TestLooper; 134 import android.util.ArraySet; 135 import android.util.SparseArray; 136 137 import androidx.test.filters.SmallTest; 138 139 import com.android.modules.utils.HandlerExecutor; 140 import com.android.modules.utils.build.SdkLevel; 141 142 import org.junit.Before; 143 import org.junit.Test; 144 import org.mockito.ArgumentCaptor; 145 import org.mockito.InOrder; 146 import org.mockito.Mock; 147 import org.mockito.Mockito; 148 import org.mockito.MockitoAnnotations; 149 150 import java.util.ArrayList; 151 import java.util.Arrays; 152 import java.util.Collections; 153 import java.util.HashMap; 154 import java.util.List; 155 import java.util.Map; 156 import java.util.Objects; 157 import java.util.Set; 158 import java.util.concurrent.Executor; 159 import java.util.function.BiConsumer; 160 import java.util.function.Consumer; 161 162 /** 163 * Unit tests for {@link android.net.wifi.WifiManager}. 164 */ 165 @SmallTest 166 public class WifiManagerTest { 167 168 private static final int ERROR_NOT_SET = -1; 169 private static final int ERROR_TEST_REASON = 5; 170 private static final int TEST_UID = 14553; 171 private static final int TEST_NETWORK_ID = 143; 172 private static final String TEST_PACKAGE_NAME = "TestPackage"; 173 private static final String TEST_FEATURE_ID = "TestFeature"; 174 private static final String TEST_COUNTRY_CODE = "US"; 175 private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; 176 private static final int TEST_SUB_ID = 3; 177 private static final String[] TEST_AP_INSTANCES = new String[] {"wlan1", "wlan2"}; 178 private static final int[] TEST_AP_FREQS = new int[] {2412, 5220}; 179 private static final int[] TEST_AP_BWS = new int[] {SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT, 180 SoftApInfo.CHANNEL_WIDTH_80MHZ}; 181 private static final MacAddress[] TEST_AP_BSSIDS = new MacAddress[] { 182 MacAddress.fromString("22:33:44:55:66:77"), 183 MacAddress.fromString("aa:bb:cc:dd:ee:ff")}; 184 private static final MacAddress[] TEST_AP_CLIENTS = new MacAddress[] { 185 MacAddress.fromString("22:33:44:aa:aa:77"), 186 MacAddress.fromString("aa:bb:cc:11:11:ff"), 187 MacAddress.fromString("22:bb:cc:11:aa:ff")}; 188 private static final String TEST_SSID = "\"Test WiFi Networks\""; 189 private static final byte[] TEST_OUI = new byte[]{0x01, 0x02, 0x03}; 190 private static final int TEST_LINK_LAYER_STATS_POLLING_INTERVAL_MS = 1000; 191 192 private static final TetheringManager.TetheringRequest TEST_TETHERING_REQUEST = 193 new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build(); 194 private static final String TEST_INTERFACE_NAME = "test-wlan0"; 195 196 @Mock Context mContext; 197 @Mock android.net.wifi.IWifiManager mWifiService; 198 @Mock ApplicationInfo mApplicationInfo; 199 @Mock WifiConfiguration mApConfig; 200 @Mock SoftApCallback mSoftApCallback; 201 @Mock TrafficStateCallback mTrafficStateCallback; 202 @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; 203 @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; 204 @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener; 205 @Mock SuggestionConnectionStatusListener mSuggestionConnectionListener; 206 @Mock 207 WifiManager.LocalOnlyConnectionFailureListener mLocalOnlyConnectionFailureListener; 208 @Mock Runnable mRunnable; 209 @Mock Executor mExecutor; 210 @Mock Executor mAnotherExecutor; 211 @Mock ActivityManager mActivityManager; 212 @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer; 213 @Mock SuggestionUserApprovalStatusListener mSuggestionUserApprovalStatusListener; 214 @Mock ActiveCountryCodeChangedCallback mActiveCountryCodeChangedCallback; 215 216 private Handler mHandler; 217 private TestLooper mLooper; 218 private WifiManager mWifiManager; 219 private WifiNetworkSuggestion mWifiNetworkSuggestion; 220 private ScanResultsCallback mScanResultsCallback; 221 private CoexCallback mCoexCallback; 222 private SubsystemRestartTrackingCallback mRestartCallback; 223 private int mRestartCallbackMethodRun = 0; // 1: restarting, 2: restarted 224 private WifiActivityEnergyInfo mWifiActivityEnergyInfo; 225 226 private HashMap<String, SoftApInfo> mTestSoftApInfoMap = new HashMap<>(); 227 private HashMap<String, List<WifiClient>> mTestWifiClientsMap = new HashMap<>(); 228 private SoftApInfo mTestApInfo1 = new SoftApInfo(); 229 private SoftApInfo mTestApInfo2 = new SoftApInfo(); 230 231 /** 232 * Util function to check public field which used for softap in WifiConfiguration 233 * same as the value in SoftApConfiguration. 234 * 235 */ compareWifiAndSoftApConfiguration( SoftApConfiguration softApConfig, WifiConfiguration wifiConfig)236 private boolean compareWifiAndSoftApConfiguration( 237 SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) { 238 // SoftApConfiguration#toWifiConfiguration() creates a config with an unquoted UTF-8 SSID 239 // instead of the double quoted behavior in the javadoc for WifiConfiguration#SSID. Thus, 240 // we need to compare the wifi config SSID directly with the unquoted UTF-8 text. 241 if (!Objects.equals(wifiConfig.SSID, softApConfig.getWifiSsid().getUtf8Text())) { 242 return false; 243 } 244 if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) { 245 return false; 246 } 247 if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) { 248 return false; 249 } 250 251 if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) { 252 return false; 253 } 254 switch (softApConfig.getSecurityType()) { 255 case SoftApConfiguration.SECURITY_TYPE_OPEN: 256 if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) { 257 return false; 258 } 259 break; 260 case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK: 261 if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) { 262 return false; 263 } 264 break; 265 default: 266 return false; 267 } 268 return true; 269 } 270 generatorTestSoftApConfig()271 private SoftApConfiguration generatorTestSoftApConfig() { 272 return new SoftApConfiguration.Builder() 273 .setSsid("TestSSID") 274 .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 275 .build(); 276 } 277 initTestInfoAndAddToTestMap(int numberOfInfos)278 private void initTestInfoAndAddToTestMap(int numberOfInfos) { 279 if (numberOfInfos > 2) return; 280 for (int i = 0; i < numberOfInfos; i++) { 281 SoftApInfo info = mTestApInfo1; 282 if (i == 1) info = mTestApInfo2; 283 info.setFrequency(TEST_AP_FREQS[i]); 284 info.setBandwidth(TEST_AP_BWS[i]); 285 info.setBssid(TEST_AP_BSSIDS[i]); 286 info.setApInstanceIdentifier(TEST_AP_INSTANCES[i]); 287 mTestSoftApInfoMap.put(TEST_AP_INSTANCES[i], info); 288 } 289 } 290 initWifiClientAndAddToTestMap(String targetInstance, int numberOfClients, int startIdx)291 private List<WifiClient> initWifiClientAndAddToTestMap(String targetInstance, 292 int numberOfClients, int startIdx) { 293 if (numberOfClients > 3) return null; 294 List<WifiClient> clients = new ArrayList<>(); 295 for (int i = startIdx; i < startIdx + numberOfClients; i++) { 296 WifiClient client = new WifiClient(TEST_AP_CLIENTS[i], targetInstance); 297 clients.add(client); 298 } 299 mTestWifiClientsMap.put(targetInstance, clients); 300 return clients; 301 } 302 303 @Before setUp()304 public void setUp() throws Exception { 305 MockitoAnnotations.initMocks(this); 306 mLooper = new TestLooper(); 307 mHandler = spy(new Handler(mLooper.getLooper())); 308 mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; 309 when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); 310 when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); 311 mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); 312 verify(mWifiService).getVerboseLoggingLevel(); 313 mWifiNetworkSuggestion = new WifiNetworkSuggestion(); 314 mScanResultsCallback = new ScanResultsCallback() { 315 @Override 316 public void onScanResultsAvailable() { 317 mRunnable.run(); 318 } 319 }; 320 if (SdkLevel.isAtLeastS()) { 321 mCoexCallback = new CoexCallback() { 322 @Override 323 public void onCoexUnsafeChannelsChanged( 324 @NonNull List<CoexUnsafeChannel> unsafeChannels, int restrictions) { 325 mRunnable.run(); 326 } 327 }; 328 AttributionSource attributionSource = mock(AttributionSource.class); 329 when(mContext.getAttributionSource()).thenReturn(attributionSource); 330 } 331 mRestartCallback = new SubsystemRestartTrackingCallback() { 332 @Override 333 public void onSubsystemRestarting() { 334 mRestartCallbackMethodRun = 1; 335 mRunnable.run(); 336 } 337 338 @Override 339 public void onSubsystemRestarted() { 340 mRestartCallbackMethodRun = 2; 341 mRunnable.run(); 342 } 343 }; 344 mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0); 345 mTestSoftApInfoMap.clear(); 346 mTestWifiClientsMap.clear(); 347 } 348 349 /** 350 * Check the call to setCoexUnsafeChannels calls WifiServiceImpl to setCoexUnsafeChannels with 351 * the provided CoexUnsafeChannels and restrictions bitmask. 352 */ 353 @Test testSetCoexUnsafeChannelsGoesToWifiServiceImpl()354 public void testSetCoexUnsafeChannelsGoesToWifiServiceImpl() throws Exception { 355 assumeTrue(SdkLevel.isAtLeastS()); 356 List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>(); 357 int restrictions = COEX_RESTRICTION_WIFI_DIRECT | COEX_RESTRICTION_SOFTAP 358 | COEX_RESTRICTION_WIFI_AWARE; 359 360 mWifiManager.setCoexUnsafeChannels(unsafeChannels, restrictions); 361 362 verify(mWifiService).setCoexUnsafeChannels(unsafeChannels, restrictions); 363 } 364 365 /** 366 * Verify an IllegalArgumentException if passed a null value for unsafeChannels. 367 */ 368 @Test testSetCoexUnsafeChannelsThrowsIllegalArgumentExceptionOnNullUnsafeChannels()369 public void testSetCoexUnsafeChannelsThrowsIllegalArgumentExceptionOnNullUnsafeChannels() { 370 assumeTrue(SdkLevel.isAtLeastS()); 371 try { 372 mWifiManager.setCoexUnsafeChannels(null, 0); 373 fail("expected IllegalArgumentException"); 374 } catch (IllegalArgumentException expected) { 375 } 376 } 377 378 /** 379 * Verify an IllegalArgumentException is thrown if callback is not provided. 380 */ 381 @Test(expected = IllegalArgumentException.class) testRegisterCoexCallbackWithNullCallback()382 public void testRegisterCoexCallbackWithNullCallback() throws Exception { 383 assumeTrue(SdkLevel.isAtLeastS()); 384 mWifiManager.registerCoexCallback(mExecutor, null); 385 } 386 387 /** 388 * Verify an IllegalArgumentException is thrown if executor is not provided. 389 */ 390 @Test(expected = IllegalArgumentException.class) testRegisterCoexCallbackWithNullExecutor()391 public void testRegisterCoexCallbackWithNullExecutor() throws Exception { 392 assumeTrue(SdkLevel.isAtLeastS()); 393 mWifiManager.registerCoexCallback(null, mCoexCallback); 394 } 395 396 /** 397 * Verify client provided callback is being called to the right callback. 398 */ 399 @Test testAddCoexCallbackAndReceiveEvent()400 public void testAddCoexCallbackAndReceiveEvent() throws Exception { 401 assumeTrue(SdkLevel.isAtLeastS()); 402 ArgumentCaptor<ICoexCallback.Stub> callbackCaptor = 403 ArgumentCaptor.forClass(ICoexCallback.Stub.class); 404 mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback); 405 verify(mWifiService).registerCoexCallback(callbackCaptor.capture()); 406 callbackCaptor.getValue().onCoexUnsafeChannelsChanged(Collections.emptyList(), 0); 407 verify(mRunnable).run(); 408 } 409 410 /** 411 * Verify client provided callback is being called to the right executor. 412 */ 413 @Test testRegisterCoexCallbackWithTheTargetExecutor()414 public void testRegisterCoexCallbackWithTheTargetExecutor() throws Exception { 415 assumeTrue(SdkLevel.isAtLeastS()); 416 ArgumentCaptor<ICoexCallback.Stub> callbackCaptor = 417 ArgumentCaptor.forClass(ICoexCallback.Stub.class); 418 mWifiManager.registerCoexCallback(mExecutor, mCoexCallback); 419 verify(mWifiService).registerCoexCallback(callbackCaptor.capture()); 420 mWifiManager.registerCoexCallback(mAnotherExecutor, mCoexCallback); 421 callbackCaptor.getValue().onCoexUnsafeChannelsChanged(Collections.emptyList(), 0); 422 verify(mExecutor, never()).execute(any(Runnable.class)); 423 verify(mAnotherExecutor).execute(any(Runnable.class)); 424 } 425 426 /** 427 * Verify client register unregister then register again, to ensure callback still works. 428 */ 429 @Test testRegisterUnregisterThenRegisterAgainWithCoexCallback()430 public void testRegisterUnregisterThenRegisterAgainWithCoexCallback() throws Exception { 431 assumeTrue(SdkLevel.isAtLeastS()); 432 ArgumentCaptor<ICoexCallback.Stub> callbackCaptor = 433 ArgumentCaptor.forClass(ICoexCallback.Stub.class); 434 mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback); 435 verify(mWifiService).registerCoexCallback(callbackCaptor.capture()); 436 mWifiManager.unregisterCoexCallback(mCoexCallback); 437 callbackCaptor.getValue().onCoexUnsafeChannelsChanged(Collections.emptyList(), 0); 438 verify(mRunnable, never()).run(); 439 mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback); 440 callbackCaptor.getValue().onCoexUnsafeChannelsChanged(Collections.emptyList(), 0); 441 verify(mRunnable).run(); 442 } 443 444 /** 445 * Verify client unregisterCoexCallback. 446 */ 447 @Test testUnregisterCoexCallback()448 public void testUnregisterCoexCallback() throws Exception { 449 assumeTrue(SdkLevel.isAtLeastS()); 450 mWifiManager.unregisterCoexCallback(mCoexCallback); 451 verify(mWifiService).unregisterCoexCallback(any()); 452 } 453 454 /** 455 * Verify client unregisterCoexCallback with null callback will cause an exception. 456 */ 457 @Test(expected = IllegalArgumentException.class) testUnregisterCoexCallbackWithNullCallback()458 public void testUnregisterCoexCallbackWithNullCallback() throws Exception { 459 assumeTrue(SdkLevel.isAtLeastS()); 460 mWifiManager.unregisterCoexCallback(null); 461 } 462 463 /** 464 * Verify that call is passed to binder. 465 */ 466 @Test testRestartWifiSubsystem()467 public void testRestartWifiSubsystem() throws Exception { 468 assumeTrue(SdkLevel.isAtLeastS()); 469 mWifiManager.restartWifiSubsystem(); 470 verify(mWifiService).restartWifiSubsystem(); 471 } 472 473 /** 474 * Verify that can register a subsystem restart tracking callback and that calls are passed 475 * through when registered and blocked once unregistered. 476 */ 477 @Test testRegisterSubsystemRestartTrackingCallback()478 public void testRegisterSubsystemRestartTrackingCallback() throws Exception { 479 assumeTrue(SdkLevel.isAtLeastS()); 480 mRestartCallbackMethodRun = 0; // none 481 ArgumentCaptor<ISubsystemRestartCallback.Stub> callbackCaptor = 482 ArgumentCaptor.forClass(ISubsystemRestartCallback.Stub.class); 483 mWifiManager.registerSubsystemRestartTrackingCallback(new SynchronousExecutor(), 484 mRestartCallback); 485 verify(mWifiService).registerSubsystemRestartCallback(callbackCaptor.capture()); 486 mWifiManager.unregisterSubsystemRestartTrackingCallback(mRestartCallback); 487 verify(mWifiService).unregisterSubsystemRestartCallback(callbackCaptor.capture()); 488 callbackCaptor.getValue().onSubsystemRestarting(); 489 verify(mRunnable, never()).run(); 490 mWifiManager.registerSubsystemRestartTrackingCallback(new SynchronousExecutor(), 491 mRestartCallback); 492 callbackCaptor.getValue().onSubsystemRestarting(); 493 assertEquals(mRestartCallbackMethodRun, 1); // restarting 494 callbackCaptor.getValue().onSubsystemRestarted(); 495 verify(mRunnable, times(2)).run(); 496 assertEquals(mRestartCallbackMethodRun, 2); // restarted 497 } 498 499 /** 500 * Check the call to startSoftAp calls WifiService to startSoftAp with the provided 501 * WifiConfiguration. Verify that the return value is propagated to the caller. 502 */ 503 @Test testStartSoftApCallsServiceWithWifiConfig()504 public void testStartSoftApCallsServiceWithWifiConfig() throws Exception { 505 when(mWifiService.startSoftAp(mApConfig, TEST_PACKAGE_NAME)).thenReturn(true); 506 assertTrue(mWifiManager.startSoftAp(mApConfig)); 507 508 when(mWifiService.startSoftAp(mApConfig, TEST_PACKAGE_NAME)).thenReturn(false); 509 assertFalse(mWifiManager.startSoftAp(mApConfig)); 510 } 511 512 /** 513 * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify 514 * that the return value is propagated to the caller. 515 */ 516 @Test testStartSoftApCallsServiceWithNullConfig()517 public void testStartSoftApCallsServiceWithNullConfig() throws Exception { 518 when(mWifiService.startSoftAp(null, TEST_PACKAGE_NAME)).thenReturn(true); 519 assertTrue(mWifiManager.startSoftAp(null)); 520 521 when(mWifiService.startSoftAp(null, TEST_PACKAGE_NAME)).thenReturn(false); 522 assertFalse(mWifiManager.startSoftAp(null)); 523 } 524 525 /** 526 * Check the call to stopSoftAp calls WifiService to stopSoftAp. 527 */ 528 @Test testStopSoftApCallsService()529 public void testStopSoftApCallsService() throws Exception { 530 when(mWifiService.stopSoftAp()).thenReturn(true); 531 assertTrue(mWifiManager.stopSoftAp()); 532 533 when(mWifiService.stopSoftAp()).thenReturn(false); 534 assertFalse(mWifiManager.stopSoftAp()); 535 } 536 537 /** 538 * Check the call to validateSoftApConfiguration calls WifiService to 539 * validateSoftApConfiguration. 540 */ 541 @Test testValidateSoftApConfigurationCallsService()542 public void testValidateSoftApConfigurationCallsService() throws Exception { 543 SoftApConfiguration apConfig = generatorTestSoftApConfig(); 544 when(mWifiService.validateSoftApConfiguration(any())).thenReturn(true); 545 assertTrue(mWifiManager.validateSoftApConfiguration(apConfig)); 546 547 when(mWifiService.validateSoftApConfiguration(any())).thenReturn(false); 548 assertFalse(mWifiManager.validateSoftApConfiguration(apConfig)); 549 } 550 551 /** 552 * Throws IllegalArgumentException when calling validateSoftApConfiguration with null. 553 */ 554 @Test testValidateSoftApConfigurationWithNullConfiguration()555 public void testValidateSoftApConfigurationWithNullConfiguration() throws Exception { 556 assertThrows(IllegalArgumentException.class, 557 () -> mWifiManager.validateSoftApConfiguration(null)); 558 } 559 560 /** 561 * Check the call to startSoftAp calls WifiService to startSoftAp with the provided 562 * WifiConfiguration. Verify that the return value is propagated to the caller. 563 */ 564 @Test testStartTetheredHotspotCallsServiceWithSoftApConfig()565 public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception { 566 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 567 when(mWifiService.startTetheredHotspot(softApConfig, TEST_PACKAGE_NAME)) 568 .thenReturn(true); 569 assertTrue(mWifiManager.startTetheredHotspot(softApConfig)); 570 571 when(mWifiService.startTetheredHotspot(softApConfig, TEST_PACKAGE_NAME)) 572 .thenReturn(false); 573 assertFalse(mWifiManager.startTetheredHotspot(softApConfig)); 574 } 575 576 /** 577 * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify 578 * that the return value is propagated to the caller. 579 */ 580 @Test testStartTetheredHotspotCallsServiceWithNullConfig()581 public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception { 582 when(mWifiService.startTetheredHotspot(null, TEST_PACKAGE_NAME)).thenReturn(true); 583 assertTrue(mWifiManager.startTetheredHotspot(null)); 584 585 when(mWifiService.startTetheredHotspot(null, TEST_PACKAGE_NAME)).thenReturn(false); 586 assertFalse(mWifiManager.startTetheredHotspot(null)); 587 } 588 589 /** 590 * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls 591 * WifiService.stopLocalOnlyHotspot. 592 */ 593 @Test testCreationAndCloseOfLocalOnlyHotspotReservation()594 public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { 595 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 596 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 597 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 598 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 599 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 600 601 callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); 602 603 assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); 604 WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); 605 assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); 606 607 callback.mRes.close(); 608 verify(mWifiService).stopLocalOnlyHotspot(); 609 } 610 611 /** 612 * Verify stopLOHS is called when try-with-resources is used properly. 613 */ 614 @Test testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()615 public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() 616 throws Exception { 617 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 618 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 619 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 620 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 621 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 622 623 callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); 624 625 try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) { 626 assertEquals(softApConfig, res.getSoftApConfiguration()); 627 WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); 628 assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); 629 } 630 631 verify(mWifiService).stopLocalOnlyHotspot(); 632 } 633 634 /** 635 * Test creation of a LocalOnlyHotspotSubscription. 636 * TODO: when registrations are tracked, verify removal on close. 637 */ 638 @Test testCreationOfLocalOnlyHotspotSubscription()639 public void testCreationOfLocalOnlyHotspotSubscription() throws Exception { 640 try (WifiManager.LocalOnlyHotspotSubscription sub = 641 mWifiManager.new LocalOnlyHotspotSubscription()) { 642 sub.close(); 643 } 644 } 645 646 public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback { 647 public boolean mOnStartedCalled = false; 648 public boolean mOnStoppedCalled = false; 649 public int mFailureReason = -1; 650 public LocalOnlyHotspotReservation mRes = null; 651 public long mCallingThreadId = -1; 652 653 @Override onStarted(LocalOnlyHotspotReservation r)654 public void onStarted(LocalOnlyHotspotReservation r) { 655 mRes = r; 656 mOnStartedCalled = true; 657 mCallingThreadId = Thread.currentThread().getId(); 658 } 659 660 @Override onStopped()661 public void onStopped() { 662 mOnStoppedCalled = true; 663 mCallingThreadId = Thread.currentThread().getId(); 664 } 665 666 @Override onFailed(int reason)667 public void onFailed(int reason) { 668 mFailureReason = reason; 669 mCallingThreadId = Thread.currentThread().getId(); 670 } 671 } 672 673 /** 674 * Verify callback is properly plumbed when called. 675 */ 676 @Test testLocalOnlyHotspotCallback()677 public void testLocalOnlyHotspotCallback() { 678 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 679 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 680 assertFalse(callback.mOnStartedCalled); 681 assertFalse(callback.mOnStoppedCalled); 682 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 683 assertEquals(null, callback.mRes); 684 685 // test onStarted 686 WifiManager.LocalOnlyHotspotReservation res = 687 mWifiManager.new LocalOnlyHotspotReservation(softApConfig); 688 callback.onStarted(res); 689 assertEquals(res, callback.mRes); 690 assertTrue(callback.mOnStartedCalled); 691 assertFalse(callback.mOnStoppedCalled); 692 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 693 694 // test onStopped 695 callback.onStopped(); 696 assertEquals(res, callback.mRes); 697 assertTrue(callback.mOnStartedCalled); 698 assertTrue(callback.mOnStoppedCalled); 699 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 700 701 // test onFailed 702 callback.onFailed(ERROR_TEST_REASON); 703 assertEquals(res, callback.mRes); 704 assertTrue(callback.mOnStartedCalled); 705 assertTrue(callback.mOnStoppedCalled); 706 assertEquals(ERROR_TEST_REASON, callback.mFailureReason); 707 } 708 709 public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver { 710 public boolean mOnRegistered = false; 711 public boolean mOnStartedCalled = false; 712 public boolean mOnStoppedCalled = false; 713 public SoftApConfiguration mConfig = null; 714 public LocalOnlyHotspotSubscription mSub = null; 715 public long mCallingThreadId = -1; 716 717 @Override onRegistered(LocalOnlyHotspotSubscription sub)718 public void onRegistered(LocalOnlyHotspotSubscription sub) { 719 mOnRegistered = true; 720 mSub = sub; 721 mCallingThreadId = Thread.currentThread().getId(); 722 } 723 724 @Override onStarted(SoftApConfiguration config)725 public void onStarted(SoftApConfiguration config) { 726 mOnStartedCalled = true; 727 mConfig = config; 728 mCallingThreadId = Thread.currentThread().getId(); 729 } 730 731 @Override onStopped()732 public void onStopped() { 733 mOnStoppedCalled = true; 734 mCallingThreadId = Thread.currentThread().getId(); 735 } 736 } 737 738 /** 739 * Verify observer is properly plumbed when called. 740 */ 741 @Test testLocalOnlyHotspotObserver()742 public void testLocalOnlyHotspotObserver() { 743 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 744 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 745 assertFalse(observer.mOnRegistered); 746 assertFalse(observer.mOnStartedCalled); 747 assertFalse(observer.mOnStoppedCalled); 748 assertEquals(null, observer.mConfig); 749 assertEquals(null, observer.mSub); 750 751 WifiManager.LocalOnlyHotspotSubscription sub = 752 mWifiManager.new LocalOnlyHotspotSubscription(); 753 observer.onRegistered(sub); 754 assertTrue(observer.mOnRegistered); 755 assertFalse(observer.mOnStartedCalled); 756 assertFalse(observer.mOnStoppedCalled); 757 assertEquals(null, observer.mConfig); 758 assertEquals(sub, observer.mSub); 759 760 observer.onStarted(softApConfig); 761 assertTrue(observer.mOnRegistered); 762 assertTrue(observer.mOnStartedCalled); 763 assertFalse(observer.mOnStoppedCalled); 764 assertEquals(softApConfig, observer.mConfig); 765 assertEquals(sub, observer.mSub); 766 767 observer.onStopped(); 768 assertTrue(observer.mOnRegistered); 769 assertTrue(observer.mOnStartedCalled); 770 assertTrue(observer.mOnStoppedCalled); 771 assertEquals(softApConfig, observer.mConfig); 772 assertEquals(sub, observer.mSub); 773 } 774 775 @Test testSetSsidsDoNotBlocklist()776 public void testSetSsidsDoNotBlocklist() throws Exception { 777 // test non-empty set 778 List<WifiSsid> expectedSsids = new ArrayList<>(); 779 expectedSsids.add(WifiSsid.fromString("\"TEST_SSID\"")); 780 mWifiManager.setSsidsAllowlist(new ArraySet<>(expectedSsids)); 781 verify(mWifiService).setSsidsAllowlist(any(), eq(expectedSsids)); 782 783 // test empty set 784 mWifiManager.setSsidsAllowlist(Collections.EMPTY_SET); 785 verify(mWifiService).setSsidsAllowlist(any(), 786 eq(Collections.EMPTY_LIST)); 787 } 788 789 /** 790 * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl. 791 */ 792 @Test testStartLocalOnlyHotspot()793 public void testStartLocalOnlyHotspot() throws Exception { 794 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 795 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 796 797 verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), 798 anyString(), nullable(String.class), eq(null), any()); 799 } 800 801 /** 802 * Verify a SecurityException is thrown for callers without proper permissions for 803 * startLocalOnlyHotspot. 804 */ 805 @Test(expected = SecurityException.class) testStartLocalOnlyHotspotThrowsSecurityException()806 public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { 807 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 808 doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( 809 any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), 810 eq(null), any()); 811 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 812 } 813 814 /** 815 * Verify an IllegalStateException is thrown for callers that already have a pending request for 816 * startLocalOnlyHotspot. 817 */ 818 @Test(expected = IllegalStateException.class) testStartLocalOnlyHotspotThrowsIllegalStateException()819 public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { 820 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 821 doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot( 822 any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), 823 eq(null), any()); 824 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 825 } 826 827 /** 828 * Verify that the handler provided by the caller is used for the callbacks. 829 */ 830 @Test testCorrectLooperIsUsedForHandler()831 public void testCorrectLooperIsUsedForHandler() throws Exception { 832 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 833 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 834 nullable(String.class), eq(null), any())).thenReturn(ERROR_INCOMPATIBLE_MODE); 835 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 836 mLooper.dispatchAll(); 837 assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); 838 verify(mContext, never()).getMainLooper(); 839 verify(mContext, never()).getMainExecutor(); 840 } 841 842 /** 843 * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg 844 * application. 845 */ 846 @Test testMainLooperIsUsedWhenHandlerNotProvided()847 public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception { 848 // record thread from looper.getThread and check ids. 849 TestLooper altLooper = new TestLooper(); 850 when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); 851 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 852 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 853 nullable(String.class), eq(null), any())).thenReturn(ERROR_INCOMPATIBLE_MODE); 854 mWifiManager.startLocalOnlyHotspot(callback, null); 855 altLooper.dispatchAll(); 856 assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); 857 assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId); 858 verify(mContext).getMainExecutor(); 859 } 860 861 /** 862 * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED 863 * message from WifiServiceImpl. 864 */ 865 @Test testOnStartedIsCalledWithReservation()866 public void testOnStartedIsCalledWithReservation() throws Exception { 867 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 868 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 869 TestLooper callbackLooper = new TestLooper(); 870 Handler callbackHandler = new Handler(callbackLooper.getLooper()); 871 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 872 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 873 when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), 874 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 875 mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); 876 callbackLooper.dispatchAll(); 877 mLooper.dispatchAll(); 878 assertFalse(callback.mOnStartedCalled); 879 assertEquals(null, callback.mRes); 880 // now trigger the callback 881 internalCallback.getValue().onHotspotStarted(softApConfig); 882 mLooper.dispatchAll(); 883 callbackLooper.dispatchAll(); 884 assertTrue(callback.mOnStartedCalled); 885 assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); 886 WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); 887 assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); 888 } 889 890 /** 891 * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED 892 * message from WifiServiceImpl when softap enabled with SAE security type. 893 */ 894 @Test testOnStartedIsCalledWithReservationAndSaeSoftApConfig()895 public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception { 896 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() 897 .setSsid("TestSSID") 898 .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) 899 .build(); 900 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 901 TestLooper callbackLooper = new TestLooper(); 902 Handler callbackHandler = new Handler(callbackLooper.getLooper()); 903 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 904 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 905 when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), 906 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 907 mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); 908 callbackLooper.dispatchAll(); 909 mLooper.dispatchAll(); 910 assertFalse(callback.mOnStartedCalled); 911 assertEquals(null, callback.mRes); 912 // now trigger the callback 913 internalCallback.getValue().onHotspotStarted(softApConfig); 914 mLooper.dispatchAll(); 915 callbackLooper.dispatchAll(); 916 assertTrue(callback.mOnStartedCalled); 917 assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); 918 assertEquals(null, callback.mRes.getWifiConfiguration()); 919 } 920 921 /** 922 * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null 923 * config. 924 */ 925 @Test testOnStartedIsCalledWithNullConfig()926 public void testOnStartedIsCalledWithNullConfig() throws Exception { 927 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 928 TestLooper callbackLooper = new TestLooper(); 929 Handler callbackHandler = new Handler(callbackLooper.getLooper()); 930 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 931 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 932 when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), 933 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 934 mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); 935 callbackLooper.dispatchAll(); 936 mLooper.dispatchAll(); 937 assertFalse(callback.mOnStartedCalled); 938 assertEquals(null, callback.mRes); 939 // now trigger the callback 940 internalCallback.getValue().onHotspotStarted(null); 941 mLooper.dispatchAll(); 942 callbackLooper.dispatchAll(); 943 assertFalse(callback.mOnStartedCalled); 944 assertEquals(ERROR_GENERIC, callback.mFailureReason); 945 } 946 947 /** 948 * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message. 949 */ 950 @Test testOnStoppedIsCalled()951 public void testOnStoppedIsCalled() throws Exception { 952 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 953 TestLooper callbackLooper = new TestLooper(); 954 Handler callbackHandler = new Handler(callbackLooper.getLooper()); 955 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 956 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 957 when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), 958 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 959 mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); 960 callbackLooper.dispatchAll(); 961 mLooper.dispatchAll(); 962 assertFalse(callback.mOnStoppedCalled); 963 // now trigger the callback 964 internalCallback.getValue().onHotspotStopped(); 965 mLooper.dispatchAll(); 966 callbackLooper.dispatchAll(); 967 assertTrue(callback.mOnStoppedCalled); 968 } 969 970 /** 971 * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message. 972 */ 973 @Test testOnFailedIsCalled()974 public void testOnFailedIsCalled() throws Exception { 975 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 976 TestLooper callbackLooper = new TestLooper(); 977 Handler callbackHandler = new Handler(callbackLooper.getLooper()); 978 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 979 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 980 when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), 981 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 982 mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); 983 callbackLooper.dispatchAll(); 984 mLooper.dispatchAll(); 985 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 986 // now trigger the callback 987 internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL); 988 mLooper.dispatchAll(); 989 callbackLooper.dispatchAll(); 990 assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); 991 } 992 993 /** 994 * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure. 995 */ 996 @Test testLocalOnlyHotspotCallbackFullOnIncompatibleMode()997 public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { 998 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 999 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1000 nullable(String.class), eq(null), any())).thenReturn(ERROR_INCOMPATIBLE_MODE); 1001 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1002 mLooper.dispatchAll(); 1003 assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); 1004 assertFalse(callback.mOnStartedCalled); 1005 assertFalse(callback.mOnStoppedCalled); 1006 assertEquals(null, callback.mRes); 1007 } 1008 1009 /** 1010 * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure. 1011 */ 1012 @Test testLocalOnlyHotspotCallbackFullOnTetheringDisallowed()1013 public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { 1014 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1015 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1016 nullable(String.class), eq(null), any())).thenReturn(ERROR_TETHERING_DISALLOWED); 1017 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1018 mLooper.dispatchAll(); 1019 assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason); 1020 assertFalse(callback.mOnStartedCalled); 1021 assertFalse(callback.mOnStoppedCalled); 1022 assertEquals(null, callback.mRes); 1023 } 1024 1025 /** 1026 * Verify a SecurityException resulting from an application without necessary permissions will 1027 * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks. 1028 */ 1029 @Test(expected = SecurityException.class) testLocalOnlyHotspotCallbackFullOnSecurityException()1030 public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { 1031 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1032 doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( 1033 any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), 1034 eq(null), any()); 1035 try { 1036 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1037 } catch (SecurityException e) { 1038 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 1039 assertFalse(callback.mOnStartedCalled); 1040 assertFalse(callback.mOnStoppedCalled); 1041 assertEquals(null, callback.mRes); 1042 throw e; 1043 } 1044 1045 } 1046 1047 /** 1048 * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when 1049 * SoftApMode fails due to a underlying error. 1050 */ 1051 @Test testLocalOnlyHotspotCallbackFullOnNoChannelError()1052 public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { 1053 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1054 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1055 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 1056 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1057 mLooper.dispatchAll(); 1058 //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); 1059 assertFalse(callback.mOnStartedCalled); 1060 assertFalse(callback.mOnStoppedCalled); 1061 assertEquals(null, callback.mRes); 1062 } 1063 1064 /** 1065 * Verify that the call to cancel a LOHS request does call stopLOHS. 1066 */ 1067 @Test testCancelLocalOnlyHotspotRequestCallsStopOnWifiService()1068 public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { 1069 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1070 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1071 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 1072 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1073 mWifiManager.cancelLocalOnlyHotspotRequest(); 1074 verify(mWifiService).stopLocalOnlyHotspot(); 1075 } 1076 1077 /** 1078 * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing 1079 * callback stored. 1080 */ 1081 @Test testCancelLocalOnlyHotspotReturnsWithoutExistingRequest()1082 public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() { 1083 mWifiManager.cancelLocalOnlyHotspotRequest(); 1084 } 1085 1086 /** 1087 * Verify that the callback is not triggered if the LOHS request was already cancelled. 1088 */ 1089 @Test testCallbackAfterLocalOnlyHotspotWasCancelled()1090 public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { 1091 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1092 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1093 nullable(String.class), eq(null), any())).thenReturn(REQUEST_REGISTERED); 1094 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1095 mWifiManager.cancelLocalOnlyHotspotRequest(); 1096 verify(mWifiService).stopLocalOnlyHotspot(); 1097 mLooper.dispatchAll(); 1098 assertEquals(ERROR_NOT_SET, callback.mFailureReason); 1099 assertFalse(callback.mOnStartedCalled); 1100 assertFalse(callback.mOnStoppedCalled); 1101 assertEquals(null, callback.mRes); 1102 } 1103 1104 /** 1105 * Verify that calling cancel LOHS request does not crash if an error callback was already 1106 * handled. 1107 */ 1108 @Test testCancelAfterLocalOnlyHotspotCallbackTriggered()1109 public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { 1110 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1111 when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), 1112 nullable(String.class), eq(null), any())).thenReturn(ERROR_INCOMPATIBLE_MODE); 1113 mWifiManager.startLocalOnlyHotspot(callback, mHandler); 1114 mLooper.dispatchAll(); 1115 assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); 1116 assertFalse(callback.mOnStartedCalled); 1117 assertFalse(callback.mOnStoppedCalled); 1118 assertEquals(null, callback.mRes); 1119 mWifiManager.cancelLocalOnlyHotspotRequest(); 1120 verify(mWifiService, never()).stopLocalOnlyHotspot(); 1121 } 1122 1123 @Test testStartLocalOnlyHotspotForwardsCustomConfig()1124 public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception { 1125 SoftApConfiguration customConfig = new SoftApConfiguration.Builder() 1126 .setSsid("customSsid") 1127 .build(); 1128 TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); 1129 mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback); 1130 verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), 1131 anyString(), nullable(String.class), eq(customConfig), any()); 1132 } 1133 1134 /** 1135 * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl. 1136 */ 1137 @Test testWatchLocalOnlyHotspot()1138 public void testWatchLocalOnlyHotspot() throws Exception { 1139 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1140 1141 mWifiManager.watchLocalOnlyHotspot(observer, mHandler); 1142 verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); 1143 } 1144 1145 /** 1146 * Verify a SecurityException is thrown for callers without proper permissions for 1147 * startWatchLocalOnlyHotspot. 1148 */ 1149 @Test(expected = SecurityException.class) testStartWatchLocalOnlyHotspotThrowsSecurityException()1150 public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception { 1151 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1152 doThrow(new SecurityException()).when(mWifiService) 1153 .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); 1154 mWifiManager.watchLocalOnlyHotspot(observer, mHandler); 1155 } 1156 1157 /** 1158 * Verify an IllegalStateException is thrown for callers that already have a pending request for 1159 * watchLocalOnlyHotspot. 1160 */ 1161 @Test(expected = IllegalStateException.class) testStartWatchLocalOnlyHotspotThrowsIllegalStateException()1162 public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception { 1163 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1164 doThrow(new IllegalStateException()).when(mWifiService) 1165 .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); 1166 mWifiManager.watchLocalOnlyHotspot(observer, mHandler); 1167 } 1168 1169 /** 1170 * Verify an IllegalArgumentException is thrown if a callback or executor is not provided. 1171 */ 1172 @Test testAddWifiVerboseLoggingStatusChangedListenerIllegalArguments()1173 public void testAddWifiVerboseLoggingStatusChangedListenerIllegalArguments() throws Exception { 1174 try { 1175 mWifiManager.addWifiVerboseLoggingStatusChangedListener( 1176 new HandlerExecutor(mHandler), null); 1177 fail("expected IllegalArgumentException - null callback"); 1178 } catch (IllegalArgumentException expected) { 1179 } 1180 try { 1181 WifiManager.WifiVerboseLoggingStatusChangedListener listener = 1182 new WifiManager.WifiVerboseLoggingStatusChangedListener() { 1183 @Override 1184 public void onWifiVerboseLoggingStatusChanged(boolean enabled) { 1185 1186 } 1187 }; 1188 mWifiManager.addWifiVerboseLoggingStatusChangedListener(null, listener); 1189 fail("expected IllegalArgumentException - null executor"); 1190 } catch (IllegalArgumentException expected) { 1191 } 1192 } 1193 1194 /** 1195 * Verify the call to addWifiVerboseLoggingStatusChangedListener and 1196 * removeWifiVerboseLoggingStatusChangedListener goes to WifiServiceImpl. 1197 */ 1198 @Test testWifiVerboseLoggingStatusChangedListenerGoesToWifiServiceImpl()1199 public void testWifiVerboseLoggingStatusChangedListenerGoesToWifiServiceImpl() 1200 throws Exception { 1201 WifiManager.WifiVerboseLoggingStatusChangedListener listener = 1202 new WifiManager.WifiVerboseLoggingStatusChangedListener() { 1203 @Override 1204 public void onWifiVerboseLoggingStatusChanged(boolean enabled) { 1205 1206 } 1207 }; 1208 mWifiManager.addWifiVerboseLoggingStatusChangedListener(new HandlerExecutor(mHandler), 1209 listener); 1210 verify(mWifiService).addWifiVerboseLoggingStatusChangedListener( 1211 any(IWifiVerboseLoggingStatusChangedListener.Stub.class)); 1212 mWifiManager.removeWifiVerboseLoggingStatusChangedListener(listener); 1213 verify(mWifiService).removeWifiVerboseLoggingStatusChangedListener( 1214 any(IWifiVerboseLoggingStatusChangedListener.Stub.class)); 1215 } 1216 1217 /** 1218 * Verify an IllegalArgumentException is thrown if a callback is not provided. 1219 */ 1220 @Test testRemoveWifiVerboseLoggingStatusChangedListenerIllegalArguments()1221 public void testRemoveWifiVerboseLoggingStatusChangedListenerIllegalArguments() 1222 throws Exception { 1223 try { 1224 mWifiManager.removeWifiVerboseLoggingStatusChangedListener(null); 1225 fail("expected IllegalArgumentException - null callback"); 1226 } catch (IllegalArgumentException expected) { 1227 } 1228 } 1229 1230 /** 1231 * Verify an IllegalArgumentException is thrown if callback is not provided. 1232 */ 1233 @Test registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()1234 public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { 1235 try { 1236 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null); 1237 fail("expected IllegalArgumentException"); 1238 } catch (IllegalArgumentException expected) { 1239 } 1240 } 1241 1242 /** 1243 * Verify an IllegalArgumentException is thrown if executor is null. 1244 */ 1245 @Test registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor()1246 public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() { 1247 try { 1248 mWifiManager.registerSoftApCallback(null, mSoftApCallback); 1249 fail("expected IllegalArgumentException"); 1250 } catch (IllegalArgumentException expected) { 1251 } 1252 } 1253 1254 /** 1255 * Verify an IllegalArgumentException is thrown if callback is not provided. 1256 */ 1257 @Test unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()1258 public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { 1259 try { 1260 mWifiManager.unregisterSoftApCallback(null); 1261 fail("expected IllegalArgumentException"); 1262 } catch (IllegalArgumentException expected) { 1263 } 1264 } 1265 1266 /** 1267 * Verify the call to registerSoftApCallback goes to WifiServiceImpl. 1268 */ 1269 @Test registerSoftApCallbackCallGoesToWifiServiceImpl()1270 public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { 1271 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1272 verify(mWifiService).registerSoftApCallback(any(ISoftApCallback.Stub.class)); 1273 } 1274 1275 /** 1276 * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl. 1277 */ 1278 @Test unregisterSoftApCallbackCallGoesToWifiServiceImpl()1279 public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { 1280 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1281 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1282 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1283 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1284 1285 mWifiManager.unregisterSoftApCallback(mSoftApCallback); 1286 verify(mWifiService).unregisterSoftApCallback(callbackCaptor.getValue()); 1287 } 1288 1289 /* 1290 * Verify client-provided callback is being called through callback proxy 1291 */ 1292 @Test softApCallbackProxyCallsOnStateChanged()1293 public void softApCallbackProxyCallsOnStateChanged() throws Exception { 1294 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1295 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1296 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1297 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1298 1299 SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0, 1300 TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME); 1301 callbackCaptor.getValue().onStateChanged(state); 1302 mLooper.dispatchAll(); 1303 ArgumentCaptor<SoftApState> softApStateCaptor = ArgumentCaptor.forClass(SoftApState.class); 1304 verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture()); 1305 assertEquals(state, softApStateCaptor.getValue()); 1306 } 1307 1308 /* 1309 * Verify client-provided callback is being called through callback proxy when registration. 1310 */ 1311 @Test softApCallbackProxyCallsOnRegistrationAndApStartedWithClientsConnected()1312 public void softApCallbackProxyCallsOnRegistrationAndApStartedWithClientsConnected() 1313 throws Exception { 1314 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1315 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1316 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1317 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1318 // Prepare test info and clients 1319 initTestInfoAndAddToTestMap(1); 1320 List<WifiClient> clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1321 // Trigger callback with registration in AP started and clients connected. 1322 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1323 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1324 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 1325 1326 mLooper.dispatchAll(); 1327 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1328 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 1329 verify(mSoftApCallback).onInfoChanged(mTestApInfo1); 1330 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1331 infos.contains(mTestApInfo1))); 1332 } 1333 1334 1335 /* 1336 * Verify client-provided callback is being called through callback proxy 1337 */ 1338 @Test softApCallbackProxyCallsOnConnectedClientsChangedEvenIfNoInfoChanged()1339 public void softApCallbackProxyCallsOnConnectedClientsChangedEvenIfNoInfoChanged() 1340 throws Exception { 1341 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1342 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1343 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1344 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1345 List<WifiClient> clientList; 1346 // Verify the register callback in disable state. 1347 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1348 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1349 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 1350 mLooper.dispatchAll(); 1351 verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>()); 1352 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1353 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1354 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1355 // After verify, reset mSoftApCallback for nex test 1356 reset(mSoftApCallback); 1357 1358 // Test first client connected 1359 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1360 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1361 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1362 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1363 mLooper.dispatchAll(); 1364 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1365 // and InfoChanged(List<SoftApInfo>) 1366 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1367 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1368 verify(mSoftApCallback, never()).onConnectedClientsChanged(mTestApInfo1, clientList); 1369 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1370 // After verify, reset mSoftApCallback for nex test 1371 reset(mSoftApCallback); 1372 1373 // Test second client connected 1374 mTestWifiClientsMap.clear(); 1375 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 2, 0); 1376 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1377 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1378 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1379 mLooper.dispatchAll(); 1380 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1381 // and InfoChanged(List<SoftApInfo>) 1382 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1383 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1384 verify(mSoftApCallback, never()).onConnectedClientsChanged(mTestApInfo1, clientList); 1385 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1386 // After verify, reset mSoftApCallback for nex test 1387 reset(mSoftApCallback); 1388 1389 // Test second client disconnect 1390 mTestWifiClientsMap.clear(); 1391 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1392 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1393 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1394 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1395 mLooper.dispatchAll(); 1396 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1397 // and InfoChanged(List<SoftApInfo>) 1398 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1399 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1400 verify(mSoftApCallback, never()).onConnectedClientsChanged(mTestApInfo1, clientList); 1401 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1402 // After verify, reset mSoftApCallback for nex test 1403 reset(mSoftApCallback); 1404 } 1405 1406 /* 1407 * Verify client-provided callback is being called through callback proxy 1408 */ 1409 @Test softApCallbackProxyCallsOnConnectedClientsChanged()1410 public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { 1411 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1412 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1413 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1414 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1415 List<WifiClient> clientList; 1416 // Verify the register callback in disable state. 1417 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1418 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1419 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 1420 mLooper.dispatchAll(); 1421 verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>()); 1422 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1423 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1424 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1425 // After verify, reset mSoftApCallback for nex test 1426 reset(mSoftApCallback); 1427 1428 // Single AP mode Test 1429 // Test info update 1430 initTestInfoAndAddToTestMap(1); 1431 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1432 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1433 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1434 mLooper.dispatchAll(); 1435 verify(mSoftApCallback).onInfoChanged(mTestApInfo1); 1436 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1437 infos.contains(mTestApInfo1))); 1438 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1439 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1440 // After verify, reset mSoftApCallback for nex test 1441 reset(mSoftApCallback); 1442 1443 // Test first client connected 1444 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1445 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1446 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1447 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1448 mLooper.dispatchAll(); 1449 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1450 // and InfoChanged(List<SoftApInfo>) 1451 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1452 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1453 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 1454 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1455 // After verify, reset mSoftApCallback for nex test 1456 reset(mSoftApCallback); 1457 1458 // Test second client connected 1459 mTestWifiClientsMap.clear(); 1460 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 2, 0); 1461 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1462 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1463 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1464 mLooper.dispatchAll(); 1465 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1466 // and InfoChanged(List<SoftApInfo>) 1467 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1468 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1469 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 1470 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1471 // After verify, reset mSoftApCallback for nex test 1472 reset(mSoftApCallback); 1473 1474 // Test second client disconnect 1475 mTestWifiClientsMap.clear(); 1476 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1477 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1478 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1479 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1480 mLooper.dispatchAll(); 1481 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1482 // and InfoChanged(List<SoftApInfo>) 1483 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1484 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1485 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 1486 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1487 // After verify, reset mSoftApCallback for nex test 1488 reset(mSoftApCallback); 1489 1490 // Test bridged mode case 1491 mTestSoftApInfoMap.clear(); 1492 initTestInfoAndAddToTestMap(2); 1493 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1494 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1495 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1496 mLooper.dispatchAll(); 1497 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1498 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1499 infos.contains(mTestApInfo1) && infos.contains(mTestApInfo2) 1500 )); 1501 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1502 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1503 // After verify, reset mSoftApCallback for nex test 1504 reset(mSoftApCallback); 1505 1506 // Test client connect to second instance 1507 List<WifiClient> clientListOnSecond = 1508 initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[1], 1, 2); // client3 to wlan2 1509 List<WifiClient> totalList = new ArrayList<>(); 1510 totalList.addAll(clientList); 1511 totalList.addAll(clientListOnSecond); 1512 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1513 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1514 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1515 mLooper.dispatchAll(); 1516 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1517 // and InfoChanged(List<SoftApInfo>) 1518 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1519 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1520 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo2, clientListOnSecond); 1521 verify(mSoftApCallback).onConnectedClientsChanged(totalList); 1522 // After verify, reset mSoftApCallback for nex test 1523 reset(mSoftApCallback); 1524 1525 // Test shutdown on second instance 1526 mTestSoftApInfoMap.clear(); 1527 mTestWifiClientsMap.clear(); 1528 initTestInfoAndAddToTestMap(1); 1529 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1530 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1531 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1532 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1533 mLooper.dispatchAll(); 1534 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1535 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1536 infos.contains(mTestApInfo1))); 1537 // second instance have client connected before, thus it should send empty list 1538 verify(mSoftApCallback).onConnectedClientsChanged( 1539 mTestApInfo2, new ArrayList<WifiClient>()); 1540 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1541 // After verify, reset mSoftApCallback for nex test 1542 reset(mSoftApCallback); 1543 1544 // Test bridged mode disable when client connected 1545 mTestSoftApInfoMap.clear(); 1546 mTestWifiClientsMap.clear(); 1547 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1548 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1549 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1550 mLooper.dispatchAll(); 1551 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1552 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1553 verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>()); 1554 verify(mSoftApCallback).onConnectedClientsChanged( 1555 mTestApInfo1, new ArrayList<WifiClient>()); 1556 // After verify, reset mSoftApCallback for nex test 1557 reset(mSoftApCallback); 1558 } 1559 1560 1561 /* 1562 * Verify client-provided callback is being called through callback proxy 1563 */ 1564 @Test softApCallbackProxyCallsOnSoftApInfoChanged()1565 public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception { 1566 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1567 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1568 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1569 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1570 // Verify the register callback in disable state. 1571 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1572 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1573 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 1574 mLooper.dispatchAll(); 1575 verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>()); 1576 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1577 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1578 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1579 // After verify, reset mSoftApCallback for nex test 1580 reset(mSoftApCallback); 1581 1582 // Single AP mode Test 1583 // Test info update 1584 initTestInfoAndAddToTestMap(1); 1585 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1586 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1587 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1588 mLooper.dispatchAll(); 1589 verify(mSoftApCallback).onInfoChanged(mTestApInfo1); 1590 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1591 infos.contains(mTestApInfo1))); 1592 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1593 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1594 // After verify, reset mSoftApCallback for nex test 1595 reset(mSoftApCallback); 1596 1597 // Test info changed 1598 SoftApInfo changedInfo = new SoftApInfo(mTestSoftApInfoMap.get(TEST_AP_INSTANCES[0])); 1599 changedInfo.setFrequency(2422); 1600 mTestSoftApInfoMap.put(TEST_AP_INSTANCES[0], changedInfo); 1601 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1602 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1603 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1604 mLooper.dispatchAll(); 1605 verify(mSoftApCallback).onInfoChanged(changedInfo); 1606 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1607 infos.contains(changedInfo))); 1608 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1609 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1610 1611 // Test Stop, all of infos is empty 1612 mTestSoftApInfoMap.clear(); 1613 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1614 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1615 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1616 mLooper.dispatchAll(); 1617 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1618 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1619 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1620 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1621 // After verify, reset mSoftApCallback for nex test 1622 reset(mSoftApCallback); 1623 } 1624 1625 /* 1626 * Verify client-provided callback is being called through callback proxy 1627 */ 1628 @Test softApCallbackProxyCallsOnSoftApInfoChangedWhenClientConnected()1629 public void softApCallbackProxyCallsOnSoftApInfoChangedWhenClientConnected() throws Exception { 1630 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1631 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1632 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1633 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1634 List<WifiClient> clientList; 1635 // Verify the register callback in disable state. 1636 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1637 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1638 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 1639 mLooper.dispatchAll(); 1640 verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>()); 1641 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1642 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1643 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1644 // After verify, reset mSoftApCallback for nex test 1645 reset(mSoftApCallback); 1646 1647 // Single AP mode Test 1648 // Test info update 1649 initTestInfoAndAddToTestMap(1); 1650 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1651 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1652 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1653 mLooper.dispatchAll(); 1654 verify(mSoftApCallback).onInfoChanged(mTestApInfo1); 1655 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1656 infos.contains(mTestApInfo1))); 1657 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1658 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1659 // After verify, reset mSoftApCallback for nex test 1660 reset(mSoftApCallback); 1661 1662 clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 1663 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1664 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1665 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1666 mLooper.dispatchAll(); 1667 // checked NO any infoChanged, includes InfoChanged(SoftApInfo) 1668 // and InfoChanged(List<SoftApInfo>) 1669 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1670 verify(mSoftApCallback, never()).onInfoChanged(any(List.class)); 1671 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 1672 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1673 // After verify, reset mSoftApCallback for nex test 1674 reset(mSoftApCallback); 1675 1676 // Test info changed when client connected 1677 SoftApInfo changedInfo = new SoftApInfo(mTestSoftApInfoMap.get(TEST_AP_INSTANCES[0])); 1678 changedInfo.setFrequency(2422); 1679 mTestSoftApInfoMap.put(TEST_AP_INSTANCES[0], changedInfo); 1680 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1681 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1682 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1683 mLooper.dispatchAll(); 1684 verify(mSoftApCallback).onInfoChanged(changedInfo); 1685 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1686 infos.contains(changedInfo))); 1687 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 1688 verify(mSoftApCallback).onConnectedClientsChanged(changedInfo, clientList); 1689 // After verify, reset mSoftApCallback for nex test 1690 reset(mSoftApCallback); 1691 1692 // Test Stop, all of infos is empty 1693 mTestSoftApInfoMap.clear(); 1694 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1695 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1696 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false); 1697 mLooper.dispatchAll(); 1698 verify(mSoftApCallback).onInfoChanged(new SoftApInfo()); 1699 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1700 verify(mSoftApCallback).onConnectedClientsChanged(any()); 1701 verify(mSoftApCallback).onConnectedClientsChanged(any(), any()); 1702 } 1703 1704 /* 1705 * Verify client-provided callback is being called through callback proxy 1706 */ 1707 @Test softApCallbackProxyCallsOnSoftApInfoChangedInBridgedMode()1708 public void softApCallbackProxyCallsOnSoftApInfoChangedInBridgedMode() throws Exception { 1709 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1710 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1711 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1712 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1713 1714 // Test bridged mode case 1715 initTestInfoAndAddToTestMap(2); 1716 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1717 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1718 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1719 mLooper.dispatchAll(); 1720 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1721 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1722 infos.contains(mTestApInfo1) && infos.contains(mTestApInfo2) 1723 )); 1724 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1725 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1726 // After verify, reset mSoftApCallback for nex test 1727 reset(mSoftApCallback); 1728 1729 // Test bridged mode case but an info changed 1730 SoftApInfo changedInfoBridgedMode = new SoftApInfo(mTestSoftApInfoMap.get( 1731 TEST_AP_INSTANCES[0])); 1732 changedInfoBridgedMode.setFrequency(2422); 1733 mTestSoftApInfoMap.put(TEST_AP_INSTANCES[0], changedInfoBridgedMode); 1734 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1735 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1736 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1737 mLooper.dispatchAll(); 1738 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1739 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1740 infos.contains(changedInfoBridgedMode) && infos.contains(mTestApInfo2) 1741 )); 1742 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1743 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1744 // After verify, reset mSoftApCallback for nex test 1745 reset(mSoftApCallback); 1746 1747 // Test bridged mode case but an instance shutdown 1748 mTestSoftApInfoMap.clear(); 1749 initTestInfoAndAddToTestMap(1); 1750 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1751 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1752 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1753 mLooper.dispatchAll(); 1754 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1755 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 1756 infos.contains(mTestApInfo1) 1757 )); 1758 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1759 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1760 // After verify, reset mSoftApCallback for nex test 1761 reset(mSoftApCallback); 1762 1763 // Test bridged mode disable case 1764 mTestSoftApInfoMap.clear(); 1765 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 1766 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 1767 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false); 1768 mLooper.dispatchAll(); 1769 verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class)); 1770 verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>()); 1771 verify(mSoftApCallback, never()).onConnectedClientsChanged(any()); 1772 verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any()); 1773 // After verify, reset mSoftApCallback for nex test 1774 reset(mSoftApCallback); 1775 } 1776 1777 /* 1778 * Verify client-provided callback is being called through callback proxy 1779 */ 1780 @Test softApCallbackProxyCallsOnCapabilityChanged()1781 public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { 1782 SoftApCapability testSoftApCapability = new SoftApCapability(0); 1783 testSoftApCapability.setMaxSupportedClients(10); 1784 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1785 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1786 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1787 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1788 1789 callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); 1790 mLooper.dispatchAll(); 1791 verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); 1792 } 1793 1794 /* 1795 * Verify client-provided callback is being called through callback proxy 1796 */ 1797 @Test softApCallbackProxyCallsOnBlockedClientConnecting()1798 public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception { 1799 WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"), 1800 TEST_AP_INSTANCES[0]); 1801 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1802 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1803 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1804 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1805 1806 callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient, 1807 WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); 1808 mLooper.dispatchAll(); 1809 verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient, 1810 WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); 1811 } 1812 1813 /* 1814 * Verify client-provided callback is being called through callback proxy on multiple events 1815 */ 1816 @Test softApCallbackProxyCallsOnMultipleUpdates()1817 public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception { 1818 SoftApCapability testSoftApCapability = new SoftApCapability(0); 1819 testSoftApCapability.setMaxSupportedClients(10); 1820 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1821 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1822 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1823 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1824 1825 SoftApState state0 = new SoftApState(WIFI_AP_STATE_ENABLING, 0, 1826 TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME); 1827 callbackCaptor.getValue().onStateChanged(state0); 1828 SoftApState state1 = new SoftApState(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL, 1829 TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME); 1830 callbackCaptor.getValue().onStateChanged(state1); 1831 callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); 1832 1833 1834 mLooper.dispatchAll(); 1835 verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); 1836 ArgumentCaptor<SoftApState> softApStateCaptor = 1837 ArgumentCaptor.forClass(SoftApState.class); 1838 verify(mSoftApCallback, times(2)).onStateChanged(softApStateCaptor.capture()); 1839 assertEquals(state0, softApStateCaptor.getAllValues().get(0)); 1840 assertEquals(state1, softApStateCaptor.getAllValues().get(1)); 1841 } 1842 1843 /* 1844 * Verify client-provided callback is being called on the correct thread 1845 */ 1846 @Test softApCallbackIsCalledOnCorrectThread()1847 public void softApCallbackIsCalledOnCorrectThread() throws Exception { 1848 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 1849 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 1850 TestLooper altLooper = new TestLooper(); 1851 Handler altHandler = new Handler(altLooper.getLooper()); 1852 mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback); 1853 verify(mWifiService).registerSoftApCallback(callbackCaptor.capture()); 1854 1855 SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0, 1856 TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME); 1857 callbackCaptor.getValue().onStateChanged(state); 1858 altLooper.dispatchAll(); 1859 ArgumentCaptor<SoftApState> softApStateCaptor = 1860 ArgumentCaptor.forClass(SoftApState.class); 1861 verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture()); 1862 SoftApState softApState = softApStateCaptor.getValue(); 1863 assertEquals(WIFI_AP_STATE_ENABLED, softApState.getState()); 1864 try { 1865 softApState.getFailureReason(); 1866 fail("getFailureReason should throw if not in failure state"); 1867 } catch (IllegalStateException e) { 1868 // Pass. 1869 } 1870 assertEquals(TEST_INTERFACE_NAME, softApState.getIface()); 1871 assertEquals(TEST_TETHERING_REQUEST, softApState.getTetheringRequest()); 1872 } 1873 1874 /** 1875 * Verify that the handler provided by the caller is used for registering soft AP callback. 1876 */ 1877 @Test testCorrectLooperIsUsedForSoftApCallbackHandler()1878 public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception { 1879 mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); 1880 mLooper.dispatchAll(); 1881 verify(mWifiService).registerSoftApCallback(any(ISoftApCallback.Stub.class)); 1882 verify(mContext, never()).getMainLooper(); 1883 verify(mContext, never()).getMainExecutor(); 1884 } 1885 1886 /** 1887 * Verify that the handler provided by the caller is used for the observer. 1888 */ 1889 @Test testCorrectLooperIsUsedForObserverHandler()1890 public void testCorrectLooperIsUsedForObserverHandler() throws Exception { 1891 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1892 mWifiManager.watchLocalOnlyHotspot(observer, mHandler); 1893 mLooper.dispatchAll(); 1894 assertTrue(observer.mOnRegistered); 1895 verify(mContext, never()).getMainLooper(); 1896 verify(mContext, never()).getMainExecutor(); 1897 } 1898 1899 /** 1900 * Verify that the main looper's thread is used if a handler is not provided by the requesting 1901 * application. 1902 */ 1903 @Test testMainLooperIsUsedWhenHandlerNotProvidedForObserver()1904 public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception { 1905 // record thread from looper.getThread and check ids. 1906 TestLooper altLooper = new TestLooper(); 1907 when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); 1908 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1909 mWifiManager.watchLocalOnlyHotspot(observer, null); 1910 altLooper.dispatchAll(); 1911 assertTrue(observer.mOnRegistered); 1912 assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId); 1913 verify(mContext).getMainExecutor(); 1914 } 1915 1916 /** 1917 * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a 1918 * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl. 1919 */ 1920 @Test testOnRegisteredIsCalledWithSubscription()1921 public void testOnRegisteredIsCalledWithSubscription() throws Exception { 1922 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1923 TestLooper observerLooper = new TestLooper(); 1924 Handler observerHandler = new Handler(observerLooper.getLooper()); 1925 assertFalse(observer.mOnRegistered); 1926 assertEquals(null, observer.mSub); 1927 mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); 1928 verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); 1929 // now trigger the callback 1930 observerLooper.dispatchAll(); 1931 mLooper.dispatchAll(); 1932 assertTrue(observer.mOnRegistered); 1933 assertNotNull(observer.mSub); 1934 } 1935 1936 /** 1937 * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a 1938 * HOTSPOT_STARTED message from WifiServiceImpl. 1939 */ 1940 @Test testObserverOnStartedIsCalledWithWifiConfig()1941 public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception { 1942 SoftApConfiguration softApConfig = generatorTestSoftApConfig(); 1943 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1944 TestLooper observerLooper = new TestLooper(); 1945 Handler observerHandler = new Handler(observerLooper.getLooper()); 1946 mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); 1947 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 1948 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 1949 verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); 1950 observerLooper.dispatchAll(); 1951 mLooper.dispatchAll(); 1952 assertFalse(observer.mOnStartedCalled); 1953 // now trigger the callback 1954 internalCallback.getValue().onHotspotStarted(softApConfig); 1955 mLooper.dispatchAll(); 1956 observerLooper.dispatchAll(); 1957 assertTrue(observer.mOnStartedCalled); 1958 assertEquals(softApConfig, observer.mConfig); 1959 } 1960 1961 /** 1962 * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a 1963 * HOTSPOT_STARTED message from WifiServiceImpl with a null config. 1964 */ 1965 @Test testObserverOnStartedNotCalledWithNullConfig()1966 public void testObserverOnStartedNotCalledWithNullConfig() throws Exception { 1967 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1968 TestLooper observerLooper = new TestLooper(); 1969 Handler observerHandler = new Handler(observerLooper.getLooper()); 1970 mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); 1971 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 1972 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 1973 verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); 1974 observerLooper.dispatchAll(); 1975 mLooper.dispatchAll(); 1976 assertFalse(observer.mOnStartedCalled); 1977 // now trigger the callback 1978 internalCallback.getValue().onHotspotStarted(null); 1979 mLooper.dispatchAll(); 1980 observerLooper.dispatchAll(); 1981 assertFalse(observer.mOnStartedCalled); 1982 assertEquals(null, observer.mConfig); 1983 } 1984 1985 1986 /** 1987 * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a 1988 * HOTSPOT_STOPPED message from WifiServiceImpl. 1989 */ 1990 @Test testObserverOnStoppedIsCalled()1991 public void testObserverOnStoppedIsCalled() throws Exception { 1992 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 1993 TestLooper observerLooper = new TestLooper(); 1994 Handler observerHandler = new Handler(observerLooper.getLooper()); 1995 mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); 1996 ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = 1997 ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); 1998 verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); 1999 observerLooper.dispatchAll(); 2000 mLooper.dispatchAll(); 2001 assertFalse(observer.mOnStoppedCalled); 2002 // now trigger the callback 2003 internalCallback.getValue().onHotspotStopped(); 2004 mLooper.dispatchAll(); 2005 observerLooper.dispatchAll(); 2006 assertTrue(observer.mOnStoppedCalled); 2007 } 2008 2009 /** 2010 * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback. 2011 */ 2012 @Test testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver()2013 public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception { 2014 mWifiManager.unregisterLocalOnlyHotspotObserver(); 2015 verifyZeroInteractions(mWifiService); 2016 } 2017 2018 /** 2019 * Verify WifiServiceImpl is called when there is a registered LOHS observer callback. 2020 */ 2021 @Test testUnregisterWifiServiceImplCalledWithRegisteredObserver()2022 public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception { 2023 TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); 2024 TestLooper observerLooper = new TestLooper(); 2025 Handler observerHandler = new Handler(observerLooper.getLooper()); 2026 mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); 2027 mWifiManager.unregisterLocalOnlyHotspotObserver(); 2028 verify(mWifiService).stopWatchLocalOnlyHotspot(); 2029 } 2030 2031 /** 2032 * Test that calls to get the current WPS config token return null and do not have any 2033 * interactions with WifiServiceImpl. 2034 */ 2035 @Test testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull()2036 public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() { 2037 assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken()); 2038 verifyNoMoreInteractions(mWifiService); 2039 } 2040 2041 2042 class WpsCallbackTester extends WpsCallback { 2043 public boolean mStarted = false; 2044 public boolean mSucceeded = false; 2045 public boolean mFailed = false; 2046 public int mFailureCode = -1; 2047 2048 @Override onStarted(String pin)2049 public void onStarted(String pin) { 2050 mStarted = true; 2051 } 2052 2053 @Override onSucceeded()2054 public void onSucceeded() { 2055 mSucceeded = true; 2056 } 2057 2058 @Override onFailed(int reason)2059 public void onFailed(int reason) { 2060 mFailed = true; 2061 mFailureCode = reason; 2062 } 2063 2064 } 2065 2066 /** 2067 * Verify that a call to start WPS immediately returns a failure. 2068 */ 2069 @Test testStartWpsImmediatelyFailsWithCallback()2070 public void testStartWpsImmediatelyFailsWithCallback() { 2071 WpsCallbackTester wpsCallback = new WpsCallbackTester(); 2072 mWifiManager.startWps(null, wpsCallback); 2073 assertTrue(wpsCallback.mFailed); 2074 assertEquals(ActionListener.FAILURE_INTERNAL_ERROR, wpsCallback.mFailureCode); 2075 assertFalse(wpsCallback.mStarted); 2076 assertFalse(wpsCallback.mSucceeded); 2077 verifyNoMoreInteractions(mWifiService); 2078 } 2079 2080 /** 2081 * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback. 2082 */ 2083 @Test testStartWpsDoesNotCallWifiServiceImpl()2084 public void testStartWpsDoesNotCallWifiServiceImpl() { 2085 mWifiManager.startWps(null, null); 2086 verifyNoMoreInteractions(mWifiService); 2087 } 2088 2089 /** 2090 * Verify that a call to cancel WPS immediately returns a failure. 2091 */ 2092 @Test testCancelWpsImmediatelyFailsWithCallback()2093 public void testCancelWpsImmediatelyFailsWithCallback() { 2094 WpsCallbackTester wpsCallback = new WpsCallbackTester(); 2095 mWifiManager.cancelWps(wpsCallback); 2096 assertTrue(wpsCallback.mFailed); 2097 assertEquals(ActionListener.FAILURE_INTERNAL_ERROR, wpsCallback.mFailureCode); 2098 assertFalse(wpsCallback.mStarted); 2099 assertFalse(wpsCallback.mSucceeded); 2100 verifyNoMoreInteractions(mWifiService); 2101 } 2102 2103 /** 2104 * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback. 2105 */ 2106 @Test testCancelWpsDoesNotCallWifiServiceImpl()2107 public void testCancelWpsDoesNotCallWifiServiceImpl() { 2108 mWifiManager.cancelWps(null); 2109 verifyNoMoreInteractions(mWifiService); 2110 } 2111 2112 /** 2113 * Verify that a successful call properly returns true. 2114 */ 2115 @Test testSetWifiApConfigurationSuccessReturnsTrue()2116 public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception { 2117 WifiConfiguration apConfig = new WifiConfiguration(); 2118 2119 when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) 2120 .thenReturn(true); 2121 assertTrue(mWifiManager.setWifiApConfiguration(apConfig)); 2122 } 2123 2124 /** 2125 * Verify that a failed call properly returns false. 2126 */ 2127 @Test testSetWifiApConfigurationFailureReturnsFalse()2128 public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception { 2129 WifiConfiguration apConfig = new WifiConfiguration(); 2130 2131 when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) 2132 .thenReturn(false); 2133 assertFalse(mWifiManager.setWifiApConfiguration(apConfig)); 2134 } 2135 2136 /** 2137 * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions. 2138 */ 2139 @Test testSetWifiApConfigurationRethrowsException()2140 public void testSetWifiApConfigurationRethrowsException() throws Exception { 2141 doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any()); 2142 2143 try { 2144 mWifiManager.setWifiApConfiguration(new WifiConfiguration()); 2145 fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); 2146 } catch (SecurityException e) { } 2147 } 2148 2149 /** 2150 * Verify that a successful call properly returns true. 2151 */ 2152 @Test testSetSoftApConfigurationSuccessReturnsTrue()2153 public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception { 2154 SoftApConfiguration apConfig = generatorTestSoftApConfig(); 2155 2156 when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) 2157 .thenReturn(true); 2158 assertTrue(mWifiManager.setSoftApConfiguration(apConfig)); 2159 } 2160 2161 /** 2162 * Verify that a failed call properly returns false. 2163 */ 2164 @Test testSetSoftApConfigurationFailureReturnsFalse()2165 public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception { 2166 SoftApConfiguration apConfig = generatorTestSoftApConfig(); 2167 2168 when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) 2169 .thenReturn(false); 2170 assertFalse(mWifiManager.setSoftApConfiguration(apConfig)); 2171 } 2172 2173 /** 2174 * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions. 2175 */ 2176 @Test testSetSoftApConfigurationRethrowsException()2177 public void testSetSoftApConfigurationRethrowsException() throws Exception { 2178 doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any()); 2179 2180 try { 2181 mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig()); 2182 fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); 2183 } catch (SecurityException e) { } 2184 } 2185 2186 /** 2187 * Check the call to startScan calls WifiService. 2188 */ 2189 @Test testStartScan()2190 public void testStartScan() throws Exception { 2191 when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( 2192 true); 2193 assertTrue(mWifiManager.startScan()); 2194 2195 when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( 2196 false); 2197 assertFalse(mWifiManager.startScan()); 2198 } 2199 2200 /** 2201 * Verify main looper is used when handler is not provided. 2202 */ 2203 @Test registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()2204 public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler() 2205 throws Exception { 2206 ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = 2207 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); 2208 mWifiManager.registerTrafficStateCallback( 2209 new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback); 2210 verify(mWifiService).registerTrafficStateCallback(callbackCaptor.capture()); 2211 2212 assertEquals(0, mLooper.dispatchAll()); 2213 callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT); 2214 assertEquals(1, mLooper.dispatchAll()); 2215 verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT); 2216 } 2217 2218 /** 2219 * Verify the call to unregisterTrafficStateCallback goes to WifiServiceImpl. 2220 */ 2221 @Test unregisterTrafficStateCallbackCallGoesToWifiServiceImpl()2222 public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception { 2223 ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = 2224 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); 2225 mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), 2226 mTrafficStateCallback); 2227 verify(mWifiService).registerTrafficStateCallback(callbackCaptor.capture()); 2228 2229 mWifiManager.unregisterTrafficStateCallback(mTrafficStateCallback); 2230 verify(mWifiService).unregisterTrafficStateCallback(callbackCaptor.getValue()); 2231 } 2232 2233 /* 2234 * Verify client-provided callback is being called through callback proxy on multiple events 2235 */ 2236 @Test trafficStateCallbackProxyCallsOnMultipleUpdates()2237 public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception { 2238 ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = 2239 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); 2240 mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), 2241 mTrafficStateCallback); 2242 verify(mWifiService).registerTrafficStateCallback(callbackCaptor.capture()); 2243 2244 InOrder inOrder = inOrder(mTrafficStateCallback); 2245 2246 callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN); 2247 callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT); 2248 callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT); 2249 2250 mLooper.dispatchAll(); 2251 inOrder.verify(mTrafficStateCallback).onStateChanged( 2252 TrafficStateCallback.DATA_ACTIVITY_IN); 2253 inOrder.verify(mTrafficStateCallback).onStateChanged( 2254 TrafficStateCallback.DATA_ACTIVITY_INOUT); 2255 inOrder.verify(mTrafficStateCallback).onStateChanged( 2256 TrafficStateCallback.DATA_ACTIVITY_OUT); 2257 } 2258 2259 /** 2260 * Verify client-provided callback is being called on the correct thread 2261 */ 2262 @Test trafficStateCallbackIsCalledOnCorrectThread()2263 public void trafficStateCallbackIsCalledOnCorrectThread() throws Exception { 2264 ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = 2265 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); 2266 TestLooper altLooper = new TestLooper(); 2267 Handler altHandler = new Handler(altLooper.getLooper()); 2268 mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler), 2269 mTrafficStateCallback); 2270 verify(mContext, never()).getMainLooper(); 2271 verify(mContext, never()).getMainExecutor(); 2272 verify(mWifiService).registerTrafficStateCallback(callbackCaptor.capture()); 2273 2274 assertEquals(0, altLooper.dispatchAll()); 2275 callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT); 2276 assertEquals(1, altLooper.dispatchAll()); 2277 verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT); 2278 } 2279 2280 /** 2281 * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl. 2282 */ 2283 @Test registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()2284 public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() 2285 throws Exception { 2286 ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor = 2287 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); 2288 mWifiManager.registerNetworkRequestMatchCallback( 2289 new HandlerExecutor(new Handler(mLooper.getLooper())), 2290 mNetworkRequestMatchCallback); 2291 verify(mWifiService).registerNetworkRequestMatchCallback(callbackCaptor.capture()); 2292 2293 INetworkRequestUserSelectionCallback iUserSelectionCallback = 2294 mock(INetworkRequestUserSelectionCallback.class); 2295 2296 assertEquals(0, mLooper.dispatchAll()); 2297 2298 callbackCaptor.getValue().onAbort(); 2299 assertEquals(1, mLooper.dispatchAll()); 2300 verify(mNetworkRequestMatchCallback).onAbort(); 2301 2302 callbackCaptor.getValue().onMatch(new ArrayList<ScanResult>()); 2303 assertEquals(1, mLooper.dispatchAll()); 2304 verify(mNetworkRequestMatchCallback).onMatch(anyList()); 2305 2306 callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration()); 2307 assertEquals(1, mLooper.dispatchAll()); 2308 verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess( 2309 any(WifiConfiguration.class)); 2310 2311 callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration()); 2312 assertEquals(1, mLooper.dispatchAll()); 2313 verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure( 2314 any(WifiConfiguration.class)); 2315 } 2316 2317 /** 2318 * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl. 2319 */ 2320 @Test unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()2321 public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { 2322 ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor = 2323 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); 2324 mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), 2325 mNetworkRequestMatchCallback); 2326 verify(mWifiService).registerNetworkRequestMatchCallback(callbackCaptor.capture()); 2327 2328 mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback); 2329 verify(mWifiService).unregisterNetworkRequestMatchCallback(callbackCaptor.getValue()); 2330 } 2331 2332 /** 2333 * Verify the call to NetworkRequestUserSelectionCallback goes to 2334 * WifiServiceImpl. 2335 */ 2336 @Test networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()2337 public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl() 2338 throws Exception { 2339 ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor = 2340 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); 2341 mWifiManager.registerNetworkRequestMatchCallback( 2342 new HandlerExecutor(new Handler(mLooper.getLooper())), 2343 mNetworkRequestMatchCallback); 2344 verify(mWifiService).registerNetworkRequestMatchCallback(callbackCaptor.capture()); 2345 2346 INetworkRequestUserSelectionCallback iUserSelectionCallback = 2347 mock(INetworkRequestUserSelectionCallback.class); 2348 ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor = 2349 ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class); 2350 callbackCaptor.getValue().onUserSelectionCallbackRegistration( 2351 iUserSelectionCallback); 2352 assertEquals(1, mLooper.dispatchAll()); 2353 verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration( 2354 userSelectionCallbackCaptor.capture()); 2355 2356 WifiConfiguration selected = new WifiConfiguration(); 2357 userSelectionCallbackCaptor.getValue().select(selected); 2358 verify(iUserSelectionCallback).select(selected); 2359 2360 userSelectionCallbackCaptor.getValue().reject(); 2361 verify(iUserSelectionCallback).reject(); 2362 } 2363 2364 /** 2365 * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and 2366 * getWifiConfigsForPasspointProfiles of WifiService in order. 2367 */ 2368 @Test testGetAllMatchingWifiConfigs()2369 public void testGetAllMatchingWifiConfigs() throws Exception { 2370 Map<String, List<ScanResult>> passpointProfiles = new HashMap<>(); 2371 passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>()); 2372 when(mWifiService.getAllMatchingPasspointProfilesForScanResults( 2373 any(List.class))).thenReturn(passpointProfiles); 2374 InOrder inOrder = inOrder(mWifiService); 2375 2376 mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>()); 2377 2378 inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class)); 2379 inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class)); 2380 } 2381 2382 /** 2383 * Check the call to getMatchingOsuProviders calls getMatchingOsuProviders of WifiService 2384 * with the provided a list of ScanResult. 2385 */ 2386 @Test testGetMatchingOsuProviders()2387 public void testGetMatchingOsuProviders() throws Exception { 2388 mWifiManager.getMatchingOsuProviders(new ArrayList<>()); 2389 2390 verify(mWifiService).getMatchingOsuProviders(any(List.class)); 2391 } 2392 2393 /** 2394 * Verify calls to {@link WifiManager#addNetworkSuggestions(List)}, 2395 * {@link WifiManager#getNetworkSuggestions()} and 2396 * {@link WifiManager#removeNetworkSuggestions(List)}. 2397 */ 2398 @Test addGetRemoveNetworkSuggestions()2399 public void addGetRemoveNetworkSuggestions() throws Exception { 2400 List<WifiNetworkSuggestion> testList = new ArrayList<>(); 2401 when(mWifiService.addNetworkSuggestions(any(List.class), anyString(), 2402 nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS); 2403 when(mWifiService.removeNetworkSuggestions(any(List.class), anyString(), anyInt())) 2404 .thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS); 2405 when(mWifiService.getNetworkSuggestions(anyString())) 2406 .thenReturn(testList); 2407 2408 assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, 2409 mWifiManager.addNetworkSuggestions(testList)); 2410 verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME), 2411 nullable(String.class)); 2412 2413 assertEquals(testList, mWifiManager.getNetworkSuggestions()); 2414 verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME)); 2415 2416 assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, 2417 mWifiManager.removeNetworkSuggestions(new ArrayList<>())); 2418 verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME), 2419 eq(ACTION_REMOVE_SUGGESTION_DISCONNECT)); 2420 } 2421 2422 @Test testRemoveNetworkSuggestionWithAction()2423 public void testRemoveNetworkSuggestionWithAction() throws Exception { 2424 when(mWifiService.removeNetworkSuggestions(anyList(), anyString(), anyInt())) 2425 .thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS); 2426 assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager 2427 .removeNetworkSuggestions(new ArrayList<>(), ACTION_REMOVE_SUGGESTION_LINGER)); 2428 verify(mWifiService).removeNetworkSuggestions(any(List.class), 2429 eq(TEST_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_LINGER)); 2430 } 2431 2432 /** 2433 * Verify call to {@link WifiManager#getMaxNumberOfNetworkSuggestionsPerApp()}. 2434 */ 2435 @Test getMaxNumberOfNetworkSuggestionsPerApp()2436 public void getMaxNumberOfNetworkSuggestionsPerApp() { 2437 when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager); 2438 when(mActivityManager.isLowRamDevice()).thenReturn(true); 2439 assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); 2440 2441 when(mActivityManager.isLowRamDevice()).thenReturn(false); 2442 assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); 2443 } 2444 2445 /** 2446 * Verify getting the factory MAC address. 2447 */ 2448 @Test testGetFactoryMacAddress()2449 public void testGetFactoryMacAddress() throws Exception { 2450 when(mWifiService.getFactoryMacAddresses()).thenReturn(TEST_MAC_ADDRESSES); 2451 assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses()); 2452 verify(mWifiService).getFactoryMacAddresses(); 2453 } 2454 2455 /** 2456 * Verify the call to getCallerConfiguredNetworks goes to WifiServiceImpl. 2457 */ 2458 @Test testGetCallerConfiguredNetworks()2459 public void testGetCallerConfiguredNetworks() throws Exception { 2460 mWifiManager.getCallerConfiguredNetworks(); 2461 verify(mWifiService).getConfiguredNetworks(any(), any(), eq(true)); 2462 } 2463 2464 @Test testGetPrivilegedConfiguredNetworks()2465 public void testGetPrivilegedConfiguredNetworks() throws Exception { 2466 mWifiManager.getPrivilegedConfiguredNetworks(); 2467 verify(mWifiService).getPrivilegedConfiguredNetworks(any(), any(), any()); 2468 } 2469 2470 /** 2471 * Verify the call to startRestrictingAutoJoinToSubscriptionId goes to WifiServiceImpl. 2472 */ 2473 @Test testStartRestrictAutoJoinToSubscriptionId()2474 public void testStartRestrictAutoJoinToSubscriptionId() throws Exception { 2475 assumeTrue(SdkLevel.isAtLeastS()); 2476 mWifiManager.startRestrictingAutoJoinToSubscriptionId(1); 2477 verify(mWifiService).startRestrictingAutoJoinToSubscriptionId(1); 2478 } 2479 2480 /** 2481 * Verify the call to stopRestrictingAutoJoinToSubscriptionId goes to WifiServiceImpl. 2482 */ 2483 @Test testStopTemporarilyDisablingAllNonCarrierMergedWifi()2484 public void testStopTemporarilyDisablingAllNonCarrierMergedWifi() throws Exception { 2485 assumeTrue(SdkLevel.isAtLeastS()); 2486 mWifiManager.stopRestrictingAutoJoinToSubscriptionId(); 2487 verify(mWifiService).stopRestrictingAutoJoinToSubscriptionId(); 2488 } 2489 2490 /** 2491 * Verify the call to addOnWifiUsabilityStatsListener goes to WifiServiceImpl. 2492 */ 2493 @Test addOnWifiUsabilityStatsListenerGoesToWifiServiceImpl()2494 public void addOnWifiUsabilityStatsListenerGoesToWifiServiceImpl() throws Exception { 2495 mExecutor = new SynchronousExecutor(); 2496 ArgumentCaptor<IOnWifiUsabilityStatsListener.Stub> callbackCaptor = 2497 ArgumentCaptor.forClass(IOnWifiUsabilityStatsListener.Stub.class); 2498 mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener); 2499 verify(mWifiService).addOnWifiUsabilityStatsListener(callbackCaptor.capture()); 2500 ContentionTimeStats[] contentionTimeStats = new ContentionTimeStats[4]; 2501 contentionTimeStats[0] = new ContentionTimeStats(1, 2, 3, 4); 2502 contentionTimeStats[1] = new ContentionTimeStats(5, 6, 7, 8); 2503 contentionTimeStats[2] = new ContentionTimeStats(9, 10, 11, 12); 2504 contentionTimeStats[3] = new ContentionTimeStats(13, 14, 15, 16); 2505 RateStats[] rateStats = new RateStats[2]; 2506 rateStats[0] = new RateStats(1, 3, 5, 7, 9, 11, 13, 15, 17); 2507 rateStats[1] = new RateStats(2, 4, 6, 8, 10, 12, 14, 16, 18); 2508 RadioStats[] radioStats = new RadioStats[2]; 2509 radioStats[0] = new RadioStats(0, 10, 11, 12, 13, 14, 15, 16, 17, 18); 2510 radioStats[1] = new RadioStats(1, 20, 21, 22, 23, 24, 25, 26, 27, 28); 2511 SparseArray<LinkStats> linkStats = new SparseArray<>(); 2512 linkStats.put(0, 2513 new LinkStats(0, WifiUsabilityStatsEntry.LINK_STATE_NOT_IN_USE, 0, -50, 300, 2514 200, 2515 188, 2, 2, 100, 300, 100, 100, 200, 2516 contentionTimeStats, rateStats)); 2517 linkStats.put(1, 2518 new LinkStats(0, WifiUsabilityStatsEntry.LINK_STATE_IN_USE, 0, -40, 860, 600, 2519 388, 2, 2, 200, 400, 100, 100, 200, 2520 contentionTimeStats, rateStats)); 2521 callbackCaptor.getValue().onWifiUsabilityStats(1, true, 2522 new WifiUsabilityStatsEntry(System.currentTimeMillis(), -50, 100, 10, 0, 5, 5, 2523 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 1, 100, 10, 2524 100, 27, contentionTimeStats, rateStats, radioStats, 101, true, true, true, 2525 0, 10, 10, true, linkStats)); 2526 verify(mOnWifiUsabilityStatsListener).onWifiUsabilityStats(anyInt(), anyBoolean(), 2527 any(WifiUsabilityStatsEntry.class)); 2528 } 2529 2530 /** 2531 * Verify the call to removeOnWifiUsabilityStatsListener goes to WifiServiceImpl. 2532 */ 2533 @Test removeOnWifiUsabilityListenerGoesToWifiServiceImpl()2534 public void removeOnWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception { 2535 mExecutor = new SynchronousExecutor(); 2536 ArgumentCaptor<IOnWifiUsabilityStatsListener.Stub> callbackCaptor = 2537 ArgumentCaptor.forClass(IOnWifiUsabilityStatsListener.Stub.class); 2538 mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener); 2539 verify(mWifiService).addOnWifiUsabilityStatsListener(callbackCaptor.capture()); 2540 2541 mWifiManager.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener); 2542 verify(mWifiService).removeOnWifiUsabilityStatsListener(callbackCaptor.getValue()); 2543 } 2544 2545 /** 2546 * Test behavior of isEnhancedOpenSupported 2547 */ 2548 @Test testIsEnhancedOpenSupported()2549 public void testIsEnhancedOpenSupported() throws Exception { 2550 when(mWifiService.getSupportedFeatures()) 2551 .thenReturn(new Long(WIFI_FEATURE_OWE)); 2552 assertTrue(mWifiManager.isEnhancedOpenSupported()); 2553 when(mWifiService.getSupportedFeatures()) 2554 .thenReturn(new Long(~WIFI_FEATURE_OWE)); 2555 assertFalse(mWifiManager.isEnhancedOpenSupported()); 2556 } 2557 2558 /** 2559 * Test behavior of isWpa3SaeSupported 2560 */ 2561 @Test testIsWpa3SaeSupported()2562 public void testIsWpa3SaeSupported() throws Exception { 2563 when(mWifiService.getSupportedFeatures()) 2564 .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE)); 2565 assertTrue(mWifiManager.isWpa3SaeSupported()); 2566 when(mWifiService.getSupportedFeatures()) 2567 .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE)); 2568 assertFalse(mWifiManager.isWpa3SaeSupported()); 2569 } 2570 2571 /** 2572 * Test behavior of isWpa3SuiteBSupported 2573 */ 2574 @Test testIsWpa3SuiteBSupported()2575 public void testIsWpa3SuiteBSupported() throws Exception { 2576 when(mWifiService.getSupportedFeatures()) 2577 .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B)); 2578 assertTrue(mWifiManager.isWpa3SuiteBSupported()); 2579 when(mWifiService.getSupportedFeatures()) 2580 .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B)); 2581 assertFalse(mWifiManager.isWpa3SuiteBSupported()); 2582 } 2583 2584 /** 2585 * Test behavior of isEasyConnectSupported 2586 */ 2587 @Test testIsEasyConnectSupported()2588 public void testIsEasyConnectSupported() throws Exception { 2589 when(mWifiService.getSupportedFeatures()) 2590 .thenReturn(new Long(WIFI_FEATURE_DPP)); 2591 assertTrue(mWifiManager.isEasyConnectSupported()); 2592 when(mWifiService.getSupportedFeatures()) 2593 .thenReturn(new Long(~WIFI_FEATURE_DPP)); 2594 assertFalse(mWifiManager.isEasyConnectSupported()); 2595 } 2596 2597 /** 2598 * Test behavior of isEasyConnectDppAkmSupported 2599 */ 2600 @Test testIsEasyConnectDppAkmSupported()2601 public void testIsEasyConnectDppAkmSupported() throws Exception { 2602 when(mWifiService.getSupportedFeatures()) 2603 .thenReturn(new Long(WIFI_FEATURE_DPP_AKM)); 2604 assertTrue(mWifiManager.isEasyConnectDppAkmSupported()); 2605 when(mWifiService.getSupportedFeatures()) 2606 .thenReturn(new Long(~WIFI_FEATURE_DPP_AKM)); 2607 assertFalse(mWifiManager.isEasyConnectDppAkmSupported()); 2608 } 2609 2610 /** 2611 * Test behavior of isEasyConnectEnrolleeResponderModeSupported 2612 */ 2613 @Test testIsEasyConnectEnrolleeResponderModeSupported()2614 public void testIsEasyConnectEnrolleeResponderModeSupported() throws Exception { 2615 assumeTrue(SdkLevel.isAtLeastS()); 2616 2617 when(mWifiService.getSupportedFeatures()) 2618 .thenReturn(new Long(WIFI_FEATURE_DPP_ENROLLEE_RESPONDER)); 2619 assertTrue(mWifiManager.isEasyConnectEnrolleeResponderModeSupported()); 2620 when(mWifiService.getSupportedFeatures()) 2621 .thenReturn(new Long(~WIFI_FEATURE_DPP_ENROLLEE_RESPONDER)); 2622 assertFalse(mWifiManager.isEasyConnectEnrolleeResponderModeSupported()); 2623 } 2624 2625 /** 2626 * Test behavior of isStaApConcurrencySupported 2627 */ 2628 @Test testIsStaApConcurrencyOpenSupported()2629 public void testIsStaApConcurrencyOpenSupported() throws Exception { 2630 when(mWifiService.getSupportedFeatures()) 2631 .thenReturn(new Long(WIFI_FEATURE_AP_STA)); 2632 assertTrue(mWifiManager.isStaApConcurrencySupported()); 2633 when(mWifiService.getSupportedFeatures()) 2634 .thenReturn(new Long(~WIFI_FEATURE_AP_STA)); 2635 assertFalse(mWifiManager.isStaApConcurrencySupported()); 2636 } 2637 2638 /** 2639 * Test behavior of isStaConcurrencySupported 2640 */ 2641 @Test testIsStaConcurrencySupported()2642 public void testIsStaConcurrencySupported() throws Exception { 2643 when(mWifiService.getSupportedFeatures()).thenReturn(0L); 2644 assertFalse(mWifiManager.isStaConcurrencyForLocalOnlyConnectionsSupported()); 2645 assertFalse(mWifiManager.isMakeBeforeBreakWifiSwitchingSupported()); 2646 assertFalse(mWifiManager.isStaConcurrencyForRestrictedConnectionsSupported()); 2647 assertFalse(mWifiManager.isStaConcurrencyForMultiInternetSupported()); 2648 2649 when(mWifiService.getSupportedFeatures()) 2650 .thenReturn(new Long(WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY)); 2651 assertTrue(mWifiManager.isStaConcurrencyForLocalOnlyConnectionsSupported()); 2652 assertFalse(mWifiManager.isMakeBeforeBreakWifiSwitchingSupported()); 2653 assertFalse(mWifiManager.isStaConcurrencyForRestrictedConnectionsSupported()); 2654 assertFalse(mWifiManager.isStaConcurrencyForMultiInternetSupported()); 2655 2656 when(mWifiService.getSupportedFeatures()) 2657 .thenReturn(new Long(WIFI_FEATURE_ADDITIONAL_STA_MBB 2658 | WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED 2659 | WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET)); 2660 assertFalse(mWifiManager.isStaConcurrencyForLocalOnlyConnectionsSupported()); 2661 assertTrue(mWifiManager.isMakeBeforeBreakWifiSwitchingSupported()); 2662 assertTrue(mWifiManager.isStaConcurrencyForRestrictedConnectionsSupported()); 2663 assertTrue(mWifiManager.isStaConcurrencyForMultiInternetSupported()); 2664 } 2665 2666 /** 2667 * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} 2668 */ 2669 @Test testAddNetwork()2670 public void testAddNetwork() throws Exception { 2671 WifiConfiguration configuration = new WifiConfiguration(); 2672 when(mWifiService.addOrUpdateNetwork(any(), anyString(), any())) 2673 .thenReturn(TEST_NETWORK_ID); 2674 2675 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 2676 2677 assertEquals(mWifiManager.addNetwork(configuration), TEST_NETWORK_ID); 2678 verify(mWifiService).addOrUpdateNetwork(eq(configuration), eq(TEST_PACKAGE_NAME), 2679 bundleCaptor.capture()); 2680 if (SdkLevel.isAtLeastS()) { 2681 assertEquals(mContext.getAttributionSource(), 2682 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 2683 } else { 2684 assertNull(bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 2685 } 2686 2687 // send a null config 2688 assertEquals(mWifiManager.addNetwork(null), -1); 2689 } 2690 2691 /** 2692 * Test {@link WifiManager#addNetworkPrivileged(WifiConfiguration)} goes to WifiService. 2693 * Also verify that an IllegalArgumentException is thrown if the input is null. 2694 */ 2695 @Test testAddNetworkPrivileged()2696 public void testAddNetworkPrivileged() throws Exception { 2697 WifiConfiguration configuration = new WifiConfiguration(); 2698 mWifiManager.addNetworkPrivileged(configuration); 2699 verify(mWifiService).addOrUpdateNetworkPrivileged(configuration, 2700 mContext.getOpPackageName()); 2701 2702 // send a null config and verify an exception is thrown 2703 try { 2704 mWifiManager.addNetworkPrivileged(null); 2705 fail("configuration is null - IllegalArgumentException is expected."); 2706 } catch (IllegalArgumentException e) { 2707 } 2708 } 2709 2710 /** 2711 * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} 2712 */ 2713 @Test testUpdateNetwork()2714 public void testUpdateNetwork() throws Exception { 2715 WifiConfiguration configuration = new WifiConfiguration(); 2716 when(mWifiService.addOrUpdateNetwork(any(), anyString(), any())) 2717 .thenReturn(TEST_NETWORK_ID); 2718 2719 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 2720 2721 configuration.networkId = TEST_NETWORK_ID; 2722 assertEquals(mWifiManager.updateNetwork(configuration), TEST_NETWORK_ID); 2723 verify(mWifiService).addOrUpdateNetwork(eq(configuration), eq(TEST_PACKAGE_NAME), 2724 bundleCaptor.capture()); 2725 if (SdkLevel.isAtLeastS()) { 2726 assertEquals(mContext.getAttributionSource(), 2727 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 2728 } else { 2729 assertNull(bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 2730 } 2731 2732 // config with invalid network ID 2733 configuration.networkId = -1; 2734 assertEquals(mWifiManager.updateNetwork(configuration), -1); 2735 2736 // send a null config 2737 assertEquals(mWifiManager.updateNetwork(null), -1); 2738 } 2739 2740 /** 2741 * Test behavior of {@link WifiManager#enableNetwork(int, boolean)} 2742 */ 2743 @Test testEnableNetwork()2744 public void testEnableNetwork() throws Exception { 2745 when(mWifiService.enableNetwork(anyInt(), anyBoolean(), anyString())) 2746 .thenReturn(true); 2747 assertTrue(mWifiManager.enableNetwork(TEST_NETWORK_ID, true)); 2748 verify(mWifiService).enableNetwork(TEST_NETWORK_ID, true, mContext.getOpPackageName()); 2749 } 2750 2751 /** 2752 * Test behavior of {@link WifiManager#disableNetwork(int)} 2753 */ 2754 @Test testDisableNetwork()2755 public void testDisableNetwork() throws Exception { 2756 when(mWifiService.disableNetwork(anyInt(), anyString())) 2757 .thenReturn(true); 2758 assertTrue(mWifiManager.disableNetwork(TEST_NETWORK_ID)); 2759 verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName()); 2760 } 2761 2762 /** 2763 * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)} 2764 * @throws Exception 2765 */ 2766 @Test testAllowAutojoin()2767 public void testAllowAutojoin() throws Exception { 2768 mWifiManager.allowAutojoin(1, true); 2769 verify(mWifiService).allowAutojoin(1, true); 2770 } 2771 2772 /** 2773 * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)} 2774 * @throws Exception 2775 */ 2776 @Test testAllowAutojoinPasspoint()2777 public void testAllowAutojoinPasspoint() throws Exception { 2778 final String fqdn = "FullyQualifiedDomainName"; 2779 mWifiManager.allowAutojoinPasspoint(fqdn, true); 2780 verify(mWifiService).allowAutojoinPasspoint(fqdn, true); 2781 } 2782 2783 /** 2784 * Test behavior of 2785 * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} 2786 */ 2787 @Test testSetMacRandomizationSettingPasspointEnabled()2788 public void testSetMacRandomizationSettingPasspointEnabled() throws Exception { 2789 final String fqdn = "FullyQualifiedDomainName"; 2790 mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true); 2791 verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true); 2792 } 2793 2794 /** 2795 * Test behavior of 2796 * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} 2797 */ 2798 @Test testSetPasspointMeteredOverride()2799 public void testSetPasspointMeteredOverride() throws Exception { 2800 final String fqdn = "FullyQualifiedDomainName"; 2801 mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); 2802 verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); 2803 } 2804 2805 /** 2806 * Test behavior of {@link WifiManager#disconnect()} 2807 */ 2808 @Test testDisconnect()2809 public void testDisconnect() throws Exception { 2810 when(mWifiService.disconnect(anyString())).thenReturn(true); 2811 assertTrue(mWifiManager.disconnect()); 2812 verify(mWifiService).disconnect(mContext.getOpPackageName()); 2813 } 2814 2815 /** 2816 * Test behavior of {@link WifiManager#reconnect()} 2817 */ 2818 @Test testReconnect()2819 public void testReconnect() throws Exception { 2820 when(mWifiService.reconnect(anyString())).thenReturn(true); 2821 assertTrue(mWifiManager.reconnect()); 2822 verify(mWifiService).reconnect(mContext.getOpPackageName()); 2823 } 2824 2825 /** 2826 * Test behavior of {@link WifiManager#reassociate()} 2827 */ 2828 @Test testReassociate()2829 public void testReassociate() throws Exception { 2830 when(mWifiService.reassociate(anyString())).thenReturn(true); 2831 assertTrue(mWifiManager.reassociate()); 2832 verify(mWifiService).reassociate(mContext.getOpPackageName()); 2833 } 2834 2835 /** 2836 * Test behavior of {@link WifiManager#getSupportedFeatures()} 2837 */ 2838 @Test testGetSupportedFeatures()2839 public void testGetSupportedFeatures() throws Exception { 2840 long supportedFeatures = 2841 WIFI_FEATURE_SCANNER 2842 | WIFI_FEATURE_PASSPOINT 2843 | WIFI_FEATURE_P2P; 2844 when(mWifiService.getSupportedFeatures()) 2845 .thenReturn(Long.valueOf(supportedFeatures)); 2846 2847 assertTrue(mWifiManager.isWifiScannerSupported()); 2848 assertTrue(mWifiManager.isPasspointSupported()); 2849 assertTrue(mWifiManager.isP2pSupported()); 2850 assertFalse(mWifiManager.isPortableHotspotSupported()); 2851 assertFalse(mWifiManager.isDeviceToDeviceRttSupported()); 2852 assertFalse(mWifiManager.isDeviceToApRttSupported()); 2853 assertFalse(mWifiManager.isPreferredNetworkOffloadSupported()); 2854 assertFalse(mWifiManager.isTdlsSupported()); 2855 assertFalse(mWifiManager.isOffChannelTdlsSupported()); 2856 assertFalse(mWifiManager.isEnhancedPowerReportingSupported()); 2857 } 2858 2859 /** 2860 * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync} 2861 * throws an exception. 2862 */ 2863 @Test(expected = NullPointerException.class) testGetWifiActivityInfoNullExecutor()2864 public void testGetWifiActivityInfoNullExecutor() throws Exception { 2865 mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener); 2866 } 2867 2868 /** 2869 * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync} 2870 * throws an exception. 2871 */ 2872 @Test(expected = NullPointerException.class) testGetWifiActivityInfoNullListener()2873 public void testGetWifiActivityInfoNullListener() throws Exception { 2874 mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null); 2875 } 2876 2877 /** Tests that the listener runs on the correct Executor. */ 2878 @Test testGetWifiActivityInfoRunsOnCorrectExecutor()2879 public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception { 2880 mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener); 2881 ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor = 2882 ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); 2883 verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); 2884 IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); 2885 listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); 2886 verify(mExecutor).execute(any()); 2887 2888 // ensure that the executor is only triggered once 2889 listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); 2890 verify(mExecutor).execute(any()); 2891 } 2892 2893 /** Tests that the correct listener runs. */ 2894 @Test testGetWifiActivityInfoRunsCorrectListener()2895 public void testGetWifiActivityInfoRunsCorrectListener() throws Exception { 2896 int[] flag = {0}; 2897 mWifiManager.getWifiActivityEnergyInfoAsync( 2898 new SynchronousExecutor(), info -> flag[0]++); 2899 ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor = 2900 ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); 2901 verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); 2902 IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); 2903 listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); 2904 assertEquals(1, flag[0]); 2905 2906 // ensure that the listener is only triggered once 2907 listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); 2908 assertEquals(1, flag[0]); 2909 } 2910 2911 /** 2912 * Test behavior of {@link WifiManager#getConnectionInfo()} 2913 */ 2914 @Test testGetConnectionInfo()2915 public void testGetConnectionInfo() throws Exception { 2916 WifiInfo wifiInfo = new WifiInfo(); 2917 when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn( 2918 wifiInfo); 2919 2920 assertEquals(wifiInfo, mWifiManager.getConnectionInfo()); 2921 } 2922 2923 /** 2924 * Test behavior of {@link WifiManager#is24GHzBandSupported()} 2925 */ 2926 @Test testIs24GHzBandSupported()2927 public void testIs24GHzBandSupported() throws Exception { 2928 when(mWifiService.is24GHzBandSupported()).thenReturn(true); 2929 assertTrue(mWifiManager.is24GHzBandSupported()); 2930 verify(mWifiService).is24GHzBandSupported(); 2931 } 2932 2933 /** 2934 * Test behavior of {@link WifiManager#is5GHzBandSupported()} 2935 */ 2936 @Test testIs5GHzBandSupported()2937 public void testIs5GHzBandSupported() throws Exception { 2938 when(mWifiService.is5GHzBandSupported()).thenReturn(true); 2939 assertTrue(mWifiManager.is5GHzBandSupported()); 2940 verify(mWifiService).is5GHzBandSupported(); 2941 } 2942 2943 /** 2944 * Test behavior of {@link WifiManager#is6GHzBandSupported()} 2945 */ 2946 @Test testIs6GHzBandSupported()2947 public void testIs6GHzBandSupported() throws Exception { 2948 when(mWifiService.is6GHzBandSupported()).thenReturn(true); 2949 assertTrue(mWifiManager.is6GHzBandSupported()); 2950 verify(mWifiService).is6GHzBandSupported(); 2951 } 2952 2953 /** 2954 * Test behavior of {@link WifiManager#is60GHzBandSupported()} 2955 */ 2956 @Test testIs60GHzBandSupported()2957 public void testIs60GHzBandSupported() throws Exception { 2958 assumeTrue(SdkLevel.isAtLeastS()); 2959 2960 when(mWifiService.is60GHzBandSupported()).thenReturn(true); 2961 assertTrue(mWifiManager.is60GHzBandSupported()); 2962 verify(mWifiService).is60GHzBandSupported(); 2963 } 2964 2965 /** 2966 * Test behavior of {@link WifiManager#isWifiStandardSupported()} 2967 */ 2968 @Test testIsWifiStandardSupported()2969 public void testIsWifiStandardSupported() throws Exception { 2970 int standard = ScanResult.WIFI_STANDARD_11AX; 2971 when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true); 2972 assertTrue(mWifiManager.isWifiStandardSupported(standard)); 2973 verify(mWifiService).isWifiStandardSupported(standard); 2974 } 2975 2976 /** 2977 * Test behavior of {@link WifiManager#getDhcpInfo()} 2978 */ 2979 @Test testGetDhcpInfo()2980 public void testGetDhcpInfo() throws Exception { 2981 DhcpInfo dhcpInfo = new DhcpInfo(); 2982 2983 when(mWifiService.getDhcpInfo(TEST_PACKAGE_NAME)).thenReturn(dhcpInfo); 2984 assertEquals(dhcpInfo, mWifiManager.getDhcpInfo()); 2985 verify(mWifiService).getDhcpInfo(TEST_PACKAGE_NAME); 2986 } 2987 2988 /** 2989 * Test behavior of {@link WifiManager#setWifiEnabled(boolean)} 2990 */ 2991 @Test testSetWifiEnabled()2992 public void testSetWifiEnabled() throws Exception { 2993 when(mWifiService.setWifiEnabled(anyString(), anyBoolean())).thenReturn(true); 2994 assertTrue(mWifiManager.setWifiEnabled(true)); 2995 verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), true); 2996 assertTrue(mWifiManager.setWifiEnabled(false)); 2997 verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false); 2998 } 2999 3000 /** 3001 * Test behavior of {@link WifiManager#connect(int, ActionListener)} 3002 */ 3003 @Test testConnectWithListener()3004 public void testConnectWithListener() throws Exception { 3005 ActionListener externalListener = mock(ActionListener.class); 3006 mWifiManager.connect(TEST_NETWORK_ID, externalListener); 3007 3008 ArgumentCaptor<IActionListener> binderListenerCaptor = 3009 ArgumentCaptor.forClass(IActionListener.class); 3010 verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), binderListenerCaptor.capture(), 3011 anyString(), any()); 3012 assertNotNull(binderListenerCaptor.getValue()); 3013 3014 // Trigger on success. 3015 binderListenerCaptor.getValue().onSuccess(); 3016 mLooper.dispatchAll(); 3017 verify(externalListener).onSuccess(); 3018 3019 // Trigger on failure. 3020 binderListenerCaptor.getValue().onFailure(WifiManager.ActionListener.FAILURE_BUSY); 3021 mLooper.dispatchAll(); 3022 verify(externalListener).onFailure(WifiManager.ActionListener.FAILURE_BUSY); 3023 } 3024 3025 /** 3026 * Test behavior of {@link WifiManager#connect(int, ActionListener)} 3027 */ 3028 @Test testConnectWithListenerHandleSecurityException()3029 public void testConnectWithListenerHandleSecurityException() throws Exception { 3030 doThrow(new SecurityException()).when(mWifiService) 3031 .connect(eq(null), anyInt(), any(IActionListener.class), anyString(), any()); 3032 ActionListener externalListener = mock(ActionListener.class); 3033 mWifiManager.connect(TEST_NETWORK_ID, externalListener); 3034 3035 mLooper.dispatchAll(); 3036 verify(externalListener).onFailure(ActionListener.FAILURE_NOT_AUTHORIZED); 3037 } 3038 3039 /** 3040 * Test behavior of {@link WifiManager#connect(int, ActionListener)} 3041 */ 3042 @Test testConnectWithListenerHandleRemoteException()3043 public void testConnectWithListenerHandleRemoteException() throws Exception { 3044 doThrow(new RemoteException()).when(mWifiService) 3045 .connect(eq(null), anyInt(), any(IActionListener.class), anyString(), any()); 3046 ActionListener externalListener = mock(ActionListener.class); 3047 mWifiManager.connect(TEST_NETWORK_ID, externalListener); 3048 3049 mLooper.dispatchAll(); 3050 verify(externalListener).onFailure(ActionListener.FAILURE_INTERNAL_ERROR); 3051 } 3052 3053 /** 3054 * Test behavior of {@link WifiManager#connect(int, ActionListener)} 3055 */ 3056 @Test testConnectWithoutListener()3057 public void testConnectWithoutListener() throws Exception { 3058 WifiConfiguration configuration = new WifiConfiguration(); 3059 mWifiManager.connect(configuration, null); 3060 3061 verify(mWifiService).connect(eq(configuration), eq(WifiConfiguration.INVALID_NETWORK_ID), 3062 eq(null), anyString(), any()); 3063 } 3064 3065 /** 3066 * Verify an IllegalArgumentException is thrown if callback is not provided. 3067 */ 3068 @Test(expected = IllegalArgumentException.class) testRegisterScanResultsCallbackWithNullCallback()3069 public void testRegisterScanResultsCallbackWithNullCallback() throws Exception { 3070 mWifiManager.registerScanResultsCallback(mExecutor, null); 3071 } 3072 3073 /** 3074 * Verify an IllegalArgumentException is thrown if executor is not provided. 3075 */ 3076 @Test(expected = IllegalArgumentException.class) testRegisterCallbackWithNullExecutor()3077 public void testRegisterCallbackWithNullExecutor() throws Exception { 3078 mWifiManager.registerScanResultsCallback(null, mScanResultsCallback); 3079 } 3080 3081 /** 3082 * Verify client provided callback is being called to the right callback. 3083 */ 3084 @Test testAddScanResultsCallbackAndReceiveEvent()3085 public void testAddScanResultsCallbackAndReceiveEvent() throws Exception { 3086 ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = 3087 ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); 3088 mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); 3089 verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); 3090 callbackCaptor.getValue().onScanResultsAvailable(); 3091 verify(mRunnable).run(); 3092 } 3093 3094 /** 3095 * Verify client provided callback is being called to the right executor. 3096 */ 3097 @Test testRegisterScanResultsCallbackWithTheTargetExecutor()3098 public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception { 3099 ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = 3100 ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); 3101 mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback); 3102 verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); 3103 mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback); 3104 callbackCaptor.getValue().onScanResultsAvailable(); 3105 verify(mExecutor, never()).execute(any(Runnable.class)); 3106 verify(mAnotherExecutor).execute(any(Runnable.class)); 3107 } 3108 3109 /** 3110 * Verify client register unregister then register again, to ensure callback still works. 3111 */ 3112 @Test testRegisterUnregisterThenRegisterAgainWithScanResultCallback()3113 public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception { 3114 ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = 3115 ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); 3116 mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); 3117 verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); 3118 mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); 3119 callbackCaptor.getValue().onScanResultsAvailable(); 3120 verify(mRunnable, never()).run(); 3121 mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); 3122 callbackCaptor.getValue().onScanResultsAvailable(); 3123 verify(mRunnable).run(); 3124 } 3125 3126 /** 3127 * Verify client unregisterScanResultsCallback. 3128 */ 3129 @Test testUnregisterScanResultsCallback()3130 public void testUnregisterScanResultsCallback() throws Exception { 3131 mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); 3132 verify(mWifiService).unregisterScanResultsCallback(any()); 3133 } 3134 3135 /** 3136 * Verify client unregisterScanResultsCallback with null callback will cause an exception. 3137 */ 3138 @Test(expected = IllegalArgumentException.class) testUnregisterScanResultsCallbackWithNullCallback()3139 public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception { 3140 mWifiManager.unregisterScanResultsCallback(null); 3141 } 3142 3143 /** 3144 * Verify an IllegalArgumentException is thrown if executor not provided. 3145 */ 3146 @Test(expected = IllegalArgumentException.class) testAddSuggestionConnectionStatusListenerWithNullExecutor()3147 public void testAddSuggestionConnectionStatusListenerWithNullExecutor() { 3148 mWifiManager.addSuggestionConnectionStatusListener(null, mSuggestionConnectionListener); 3149 } 3150 3151 /** 3152 * Verify an IllegalArgumentException is thrown if listener is not provided. 3153 */ 3154 @Test(expected = IllegalArgumentException.class) testAddSuggestionConnectionStatusListenerWithNullListener()3155 public void testAddSuggestionConnectionStatusListenerWithNullListener() { 3156 mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null); 3157 } 3158 3159 /** 3160 * Verify client provided listener is being called to the right listener. 3161 */ 3162 @Test testAddSuggestionConnectionStatusListenerAndReceiveEvent()3163 public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception { 3164 int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; 3165 ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor = 3166 ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); 3167 Executor executor = new SynchronousExecutor(); 3168 mWifiManager.addSuggestionConnectionStatusListener(executor, 3169 mSuggestionConnectionListener); 3170 verify(mWifiService).registerSuggestionConnectionStatusListener(callbackCaptor.capture(), 3171 anyString(), nullable(String.class)); 3172 callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode); 3173 verify(mSuggestionConnectionListener).onConnectionStatus(any(WifiNetworkSuggestion.class), 3174 eq(errorCode)); 3175 } 3176 3177 /** 3178 * Verify client provided listener is being called to the right executor. 3179 */ 3180 @Test testAddSuggestionConnectionStatusListenerWithTheTargetExecutor()3181 public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception { 3182 int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; 3183 ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor = 3184 ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); 3185 mWifiManager.addSuggestionConnectionStatusListener(mExecutor, 3186 mSuggestionConnectionListener); 3187 verify(mWifiService).registerSuggestionConnectionStatusListener(callbackCaptor.capture(), 3188 anyString(), nullable(String.class)); 3189 callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode); 3190 verify(mExecutor).execute(any(Runnable.class)); 3191 } 3192 3193 /** 3194 * Verify an IllegalArgumentException is thrown if listener is not provided. 3195 */ 3196 @Test(expected = IllegalArgumentException.class) testRemoveSuggestionConnectionListenerWithNullListener()3197 public void testRemoveSuggestionConnectionListenerWithNullListener() { 3198 mWifiManager.removeSuggestionConnectionStatusListener(null); 3199 } 3200 3201 /** 3202 * Verify removeSuggestionConnectionListener. 3203 */ 3204 @Test testRemoveSuggestionConnectionListener()3205 public void testRemoveSuggestionConnectionListener() throws Exception { 3206 ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor = 3207 ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); 3208 mWifiManager.addSuggestionConnectionStatusListener(mExecutor, 3209 mSuggestionConnectionListener); 3210 verify(mWifiService).registerSuggestionConnectionStatusListener(callbackCaptor.capture(), 3211 anyString(), nullable(String.class)); 3212 3213 mWifiManager.removeSuggestionConnectionStatusListener(mSuggestionConnectionListener); 3214 verify(mWifiService).unregisterSuggestionConnectionStatusListener( 3215 eq(callbackCaptor.getValue()), anyString()); 3216 } 3217 3218 /** Test {@link WifiManager#calculateSignalLevel(int)} */ 3219 @Test testCalculateSignalLevel()3220 public void testCalculateSignalLevel() throws Exception { 3221 when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3); 3222 int actual = mWifiManager.calculateSignalLevel(-60); 3223 verify(mWifiService).calculateSignalLevel(-60); 3224 assertEquals(3, actual); 3225 } 3226 3227 /** Test {@link WifiManager#getMaxSignalLevel()} */ 3228 @Test testGetMaxSignalLevel()3229 public void testGetMaxSignalLevel() throws Exception { 3230 when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4); 3231 int actual = mWifiManager.getMaxSignalLevel(); 3232 verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE); 3233 assertEquals(4, actual); 3234 } 3235 3236 /* 3237 * Test behavior of isWapiSupported 3238 * @throws Exception 3239 */ 3240 @Test testIsWapiSupported()3241 public void testIsWapiSupported() throws Exception { 3242 when(mWifiService.getSupportedFeatures()) 3243 .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI)); 3244 assertTrue(mWifiManager.isWapiSupported()); 3245 when(mWifiService.getSupportedFeatures()) 3246 .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI)); 3247 assertFalse(mWifiManager.isWapiSupported()); 3248 } 3249 3250 /* 3251 * Test that DPP channel list is parsed correctly 3252 */ 3253 @Test testparseDppChannelList()3254 public void testparseDppChannelList() throws Exception { 3255 String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48"; 3256 SparseArray<int[]> expectedResult = new SparseArray<>(); 3257 expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}); 3258 expectedResult.append(115, new int[]{36, 40, 44, 48}); 3259 3260 SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList); 3261 assertEquals(expectedResult.size(), result.size()); 3262 3263 int index = 0; 3264 int key; 3265 3266 // Compare the two primitive int arrays 3267 do { 3268 try { 3269 key = result.keyAt(index); 3270 } catch (java.lang.ArrayIndexOutOfBoundsException e) { 3271 break; 3272 } 3273 int[] expected = expectedResult.get(key); 3274 int[] output = result.get(key); 3275 assertEquals(expected.length, output.length); 3276 for (int i = 0; i < output.length; i++) { 3277 assertEquals(expected[i], output[i]); 3278 } 3279 index++; 3280 } while (true); 3281 } 3282 3283 /* 3284 * Test that DPP channel list parser gracefully fails for invalid input 3285 */ 3286 @Test testparseDppChannelListWithInvalidFormats()3287 public void testparseDppChannelListWithInvalidFormats() throws Exception { 3288 String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48"; 3289 SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList); 3290 assertEquals(result.size(), 0); 3291 3292 channelList = "ajgalskgjalskjg3-09683dh"; 3293 result = WifiManager.parseDppChannelList(channelList); 3294 assertEquals(result.size(), 0); 3295 3296 channelList = "13/abc,46////"; 3297 result = WifiManager.parseDppChannelList(channelList); 3298 assertEquals(result.size(), 0); 3299 3300 channelList = "11/4,5,13/"; 3301 result = WifiManager.parseDppChannelList(channelList); 3302 assertEquals(result.size(), 0); 3303 3304 channelList = "/24,6"; 3305 result = WifiManager.parseDppChannelList(channelList); 3306 assertEquals(result.size(), 0); 3307 } 3308 3309 /** 3310 * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults. 3311 */ 3312 @Test testGetWifiConfigsForMatchedNetworkSuggestions()3313 public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception { 3314 List<WifiConfiguration> testResults = new ArrayList<>(); 3315 testResults.add(new WifiConfiguration()); 3316 3317 when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class))) 3318 .thenReturn(testResults); 3319 assertEquals(testResults, mWifiManager 3320 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>())); 3321 } 3322 3323 /** 3324 * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl. 3325 */ 3326 @Test setWifiConnectedNetworkScorerGoesToWifiServiceImpl()3327 public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { 3328 mExecutor = new SynchronousExecutor(); 3329 mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); 3330 verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), 3331 any(IWifiConnectedNetworkScorer.Stub.class)); 3332 } 3333 3334 /** 3335 * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl. 3336 */ 3337 @Test clearWifiConnectedNetworkScorerGoesToWifiServiceImpl()3338 public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { 3339 mExecutor = new SynchronousExecutor(); 3340 mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); 3341 verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), 3342 any(IWifiConnectedNetworkScorer.Stub.class)); 3343 3344 mWifiManager.clearWifiConnectedNetworkScorer(); 3345 verify(mWifiService).clearWifiConnectedNetworkScorer(); 3346 } 3347 3348 /** 3349 * Verify that Wi-Fi connected scorer receives score update observer after registeration. 3350 */ 3351 @Test verifyScorerReceiveScoreUpdateObserverAfterRegistration()3352 public void verifyScorerReceiveScoreUpdateObserverAfterRegistration() throws Exception { 3353 mExecutor = new SynchronousExecutor(); 3354 mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); 3355 ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor = 3356 ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); 3357 verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), 3358 scorerCaptor.capture()); 3359 scorerCaptor.getValue().onSetScoreUpdateObserver(any()); 3360 mLooper.dispatchAll(); 3361 verify(mWifiConnectedNetworkScorer).onSetScoreUpdateObserver(any()); 3362 } 3363 3364 /** 3365 * Verify that Wi-Fi connected scorer receives session ID when onStart/onStop methods 3366 * are called. 3367 */ 3368 @Test verifyScorerReceiveSessionIdWhenStartStopIsCalled()3369 public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception { 3370 mExecutor = new SynchronousExecutor(); 3371 mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); 3372 ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor = 3373 ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); 3374 verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), 3375 callbackCaptor.capture()); 3376 callbackCaptor.getValue().onStart(new WifiConnectedSessionInfo.Builder(10) 3377 .setUserSelected(true) 3378 .build()); 3379 callbackCaptor.getValue().onStop(10); 3380 mLooper.dispatchAll(); 3381 verify(mWifiConnectedNetworkScorer).onStart( 3382 argThat(sessionInfo -> sessionInfo.getSessionId() == 10 3383 && sessionInfo.isUserSelected())); 3384 verify(mWifiConnectedNetworkScorer).onStop(10); 3385 } 3386 3387 /** 3388 * Verify the call to setWifiScoringEnabled goes to WifiServiceImpl. 3389 */ 3390 @Test setWifiScoringEnabledGoesToWifiServiceImpl()3391 public void setWifiScoringEnabledGoesToWifiServiceImpl() throws Exception { 3392 mWifiManager.setWifiScoringEnabled(true); 3393 verify(mWifiService).setWifiScoringEnabled(true); 3394 } 3395 3396 /** 3397 * Verify the call to addCustomDhcpOptions goes to WifiServiceImpl. 3398 */ 3399 @Test addCustomDhcpOptionsGoesToWifiServiceImpl()3400 public void addCustomDhcpOptionsGoesToWifiServiceImpl() throws Exception { 3401 assumeTrue(SdkLevel.isAtLeastT()); 3402 mWifiManager.addCustomDhcpOptions( 3403 WifiSsid.fromString(TEST_SSID), TEST_OUI, new ArrayList<DhcpOption>()); 3404 verify(mWifiService).addCustomDhcpOptions( 3405 WifiSsid.fromString(TEST_SSID), TEST_OUI, new ArrayList<DhcpOption>()); 3406 } 3407 3408 /** 3409 * Verify the call to removeCustomDhcpOptions goes to WifiServiceImpl. 3410 */ 3411 @Test removeCustomDhcpOptionsGoesToWifiServiceImpl()3412 public void removeCustomDhcpOptionsGoesToWifiServiceImpl() throws Exception { 3413 assumeTrue(SdkLevel.isAtLeastT()); 3414 mWifiManager.removeCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), TEST_OUI); 3415 verify(mWifiService).removeCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), TEST_OUI); 3416 } 3417 3418 @Test testScanThrottle()3419 public void testScanThrottle() throws Exception { 3420 mWifiManager.setScanThrottleEnabled(true); 3421 verify(mWifiService).setScanThrottleEnabled(true); 3422 3423 when(mWifiService.isScanThrottleEnabled()).thenReturn(false); 3424 assertFalse(mWifiManager.isScanThrottleEnabled()); 3425 verify(mWifiService).isScanThrottleEnabled(); 3426 } 3427 3428 @Test testAutoWakeup()3429 public void testAutoWakeup() throws Exception { 3430 mWifiManager.setAutoWakeupEnabled(true); 3431 verify(mWifiService).setAutoWakeupEnabled(true); 3432 3433 when(mWifiService.isAutoWakeupEnabled()).thenReturn(false); 3434 assertFalse(mWifiManager.isAutoWakeupEnabled()); 3435 verify(mWifiService).isAutoWakeupEnabled(); 3436 } 3437 3438 3439 @Test testScanAvailable()3440 public void testScanAvailable() throws Exception { 3441 mWifiManager.setScanAlwaysAvailable(true); 3442 verify(mWifiService).setScanAlwaysAvailable(true, TEST_PACKAGE_NAME); 3443 3444 when(mWifiService.isScanAlwaysAvailable()).thenReturn(false); 3445 assertFalse(mWifiManager.isScanAlwaysAvailable()); 3446 verify(mWifiService).isScanAlwaysAvailable(); 3447 } 3448 3449 @Test testSetCarrierNetworkOffload()3450 public void testSetCarrierNetworkOffload() throws Exception { 3451 mWifiManager.setCarrierNetworkOffloadEnabled(TEST_SUB_ID, true, false); 3452 verify(mWifiService).setCarrierNetworkOffloadEnabled(TEST_SUB_ID, 3453 true, false); 3454 } 3455 3456 @Test testGetCarrierNetworkOffload()3457 public void testGetCarrierNetworkOffload() throws Exception { 3458 when(mWifiService.isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false)).thenReturn(true); 3459 assertTrue(mWifiManager.isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false)); 3460 verify(mWifiService).isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false); 3461 } 3462 3463 3464 /** 3465 * Verify an IllegalArgumentException is thrown if listener is not provided. 3466 */ 3467 @Test(expected = IllegalArgumentException.class) testRemoveSuggestionUserApprovalStatusListenerWithNullListener()3468 public void testRemoveSuggestionUserApprovalStatusListenerWithNullListener() { 3469 mWifiManager.removeSuggestionUserApprovalStatusListener(null); 3470 } 3471 3472 3473 /** 3474 * Verify removeSuggestionUserApprovalStatusListener. 3475 */ 3476 @Test testRemoveSuggestionUserApprovalStatusListener()3477 public void testRemoveSuggestionUserApprovalStatusListener() throws Exception { 3478 ArgumentCaptor<ISuggestionUserApprovalStatusListener.Stub> callbackCaptor = 3479 ArgumentCaptor.forClass(ISuggestionUserApprovalStatusListener.Stub.class); 3480 mWifiManager.addSuggestionUserApprovalStatusListener(mExecutor, 3481 mSuggestionUserApprovalStatusListener); 3482 verify(mWifiService).addSuggestionUserApprovalStatusListener(callbackCaptor.capture(), 3483 anyString()); 3484 3485 mWifiManager.removeSuggestionUserApprovalStatusListener( 3486 mSuggestionUserApprovalStatusListener); 3487 verify(mWifiService).removeSuggestionUserApprovalStatusListener( 3488 eq(callbackCaptor.getValue()), anyString()); 3489 } 3490 3491 /** 3492 * Verify an IllegalArgumentException is thrown if executor not provided. 3493 */ 3494 @Test(expected = NullPointerException.class) testAddSuggestionUserApprovalStatusListenerWithNullExecutor()3495 public void testAddSuggestionUserApprovalStatusListenerWithNullExecutor() { 3496 mWifiManager.addSuggestionUserApprovalStatusListener(null, 3497 mSuggestionUserApprovalStatusListener); 3498 } 3499 3500 /** 3501 * Verify an IllegalArgumentException is thrown if listener is not provided. 3502 */ 3503 @Test(expected = NullPointerException.class) testAddSuggestionUserApprovalStatusListenerWithNullListener()3504 public void testAddSuggestionUserApprovalStatusListenerWithNullListener() { 3505 mWifiManager.addSuggestionUserApprovalStatusListener(mExecutor, null); 3506 } 3507 3508 /** 3509 * Verify client provided listener is being called to the right listener. 3510 */ 3511 @Test testAddSuggestionUserApprovalStatusListenerAndReceiveEvent()3512 public void testAddSuggestionUserApprovalStatusListenerAndReceiveEvent() throws Exception { 3513 ArgumentCaptor<ISuggestionUserApprovalStatusListener.Stub> callbackCaptor = 3514 ArgumentCaptor.forClass(ISuggestionUserApprovalStatusListener.Stub.class); 3515 Executor executor = new SynchronousExecutor(); 3516 mWifiManager.addSuggestionUserApprovalStatusListener(executor, 3517 mSuggestionUserApprovalStatusListener); 3518 verify(mWifiService).addSuggestionUserApprovalStatusListener(callbackCaptor.capture(), 3519 anyString()); 3520 callbackCaptor.getValue().onUserApprovalStatusChange( 3521 WifiManager.STATUS_SUGGESTION_APPROVAL_APPROVED_BY_USER); 3522 verify(mSuggestionUserApprovalStatusListener).onUserApprovalStatusChange( 3523 WifiManager.STATUS_SUGGESTION_APPROVAL_APPROVED_BY_USER); 3524 } 3525 3526 /** 3527 * Verify client provided listener is being called to the right executor. 3528 */ 3529 @Test testAddSuggestionUserApprovalStatusListenerWithTheTargetExecutor()3530 public void testAddSuggestionUserApprovalStatusListenerWithTheTargetExecutor() 3531 throws Exception { 3532 ArgumentCaptor<ISuggestionUserApprovalStatusListener.Stub> callbackCaptor = 3533 ArgumentCaptor.forClass(ISuggestionUserApprovalStatusListener.Stub.class); 3534 mWifiManager.addSuggestionUserApprovalStatusListener(mExecutor, 3535 mSuggestionUserApprovalStatusListener); 3536 verify(mWifiService).addSuggestionUserApprovalStatusListener(callbackCaptor.capture(), 3537 anyString()); 3538 callbackCaptor.getValue().onUserApprovalStatusChange( 3539 WifiManager.STATUS_SUGGESTION_APPROVAL_APPROVED_BY_USER); 3540 verify(mExecutor).execute(any(Runnable.class)); 3541 } 3542 3543 @Test testSetExternalPnoScanRequestNullFrequencies()3544 public void testSetExternalPnoScanRequestNullFrequencies() throws Exception { 3545 mWifiManager.setExternalPnoScanRequest(Collections.EMPTY_LIST, null, 3546 mock(Executor.class), mock(WifiManager.PnoScanResultsCallback.class)); 3547 // null frequencies should get converted to empty array 3548 verify(mWifiService).setExternalPnoScanRequest(any(), any(), eq(Collections.EMPTY_LIST), 3549 eq(new int[0]), any(), any()); 3550 } 3551 3552 @Test testSetEmergencyScanRequestInProgress()3553 public void testSetEmergencyScanRequestInProgress() throws Exception { 3554 mWifiManager.setEmergencyScanRequestInProgress(true); 3555 verify(mWifiService).setEmergencyScanRequestInProgress(true); 3556 3557 mWifiManager.setEmergencyScanRequestInProgress(false); 3558 verify(mWifiService).setEmergencyScanRequestInProgress(false); 3559 } 3560 3561 @Test testRemoveAppState()3562 public void testRemoveAppState() throws Exception { 3563 mWifiManager.removeAppState(TEST_UID, TEST_PACKAGE_NAME); 3564 verify(mWifiService).removeAppState(TEST_UID, TEST_PACKAGE_NAME); 3565 } 3566 3567 /** 3568 * Test behavior of isPasspointTermsAndConditionsSupported 3569 */ 3570 @Test testIsPasspointTermsAndConditionsSupported()3571 public void testIsPasspointTermsAndConditionsSupported() throws Exception { 3572 when(mWifiService.getSupportedFeatures()) 3573 .thenReturn(new Long(WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS)); 3574 assertTrue(mWifiManager.isPasspointTermsAndConditionsSupported()); 3575 when(mWifiService.getSupportedFeatures()) 3576 .thenReturn(new Long(~WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS)); 3577 assertFalse(mWifiManager.isPasspointTermsAndConditionsSupported()); 3578 } 3579 3580 /** 3581 * Verify the call to setOverrideCountryCode goes to WifiServiceImpl. 3582 */ 3583 @Test testSetOverrideCountryCode()3584 public void testSetOverrideCountryCode() throws Exception { 3585 assumeTrue(SdkLevel.isAtLeastS()); 3586 mWifiManager.setOverrideCountryCode(TEST_COUNTRY_CODE); 3587 verify(mWifiService).setOverrideCountryCode(eq(TEST_COUNTRY_CODE)); 3588 } 3589 3590 /** 3591 * Verify the call to clearOverrideCountryCode goes to WifiServiceImpl. 3592 */ 3593 @Test testClearOverrideCountryCode()3594 public void testClearOverrideCountryCode() throws Exception { 3595 assumeTrue(SdkLevel.isAtLeastS()); 3596 mWifiManager.clearOverrideCountryCode(); 3597 verify(mWifiService).clearOverrideCountryCode(); 3598 } 3599 3600 /** 3601 * Verify the call to setDefaultCountryCode goes to WifiServiceImpl. 3602 */ 3603 @Test testSetDefaultCountryCode()3604 public void testSetDefaultCountryCode() throws Exception { 3605 assumeTrue(SdkLevel.isAtLeastS()); 3606 mWifiManager.setDefaultCountryCode(TEST_COUNTRY_CODE); 3607 verify(mWifiService).setDefaultCountryCode(eq(TEST_COUNTRY_CODE)); 3608 } 3609 3610 /** 3611 * Test behavior of flushPasspointAnqpCache 3612 */ 3613 @Test testFlushPasspointAnqpCache()3614 public void testFlushPasspointAnqpCache() throws Exception { 3615 mWifiManager.flushPasspointAnqpCache(); 3616 verify(mWifiService).flushPasspointAnqpCache(anyString()); 3617 } 3618 3619 @Test testSetPnoScanState()3620 public void testSetPnoScanState() throws Exception { 3621 mWifiManager.setPnoScanState(WifiManager.PNO_SCAN_STATE_DISABLED_UNTIL_WIFI_TOGGLE); 3622 verify(mWifiService).setPnoScanEnabled(false, true, TEST_PACKAGE_NAME); 3623 3624 mWifiManager.setPnoScanState(WifiManager.PNO_SCAN_STATE_DISABLED_UNTIL_REBOOT); 3625 verify(mWifiService).setPnoScanEnabled(false, false, TEST_PACKAGE_NAME); 3626 3627 mWifiManager.setPnoScanState(WifiManager.PNO_SCAN_STATE_ENABLED); 3628 verify(mWifiService).setPnoScanEnabled(eq(true), anyBoolean(), any()); 3629 3630 assertThrows(IllegalArgumentException.class, () -> mWifiManager.setPnoScanState(999)); 3631 } 3632 3633 3634 3635 /** 3636 * Test behavior of isDecoratedIdentitySupported 3637 */ 3638 @Test testIsDecoratedIdentitySupported()3639 public void testIsDecoratedIdentitySupported() throws Exception { 3640 when(mWifiService.getSupportedFeatures()) 3641 .thenReturn(new Long(WIFI_FEATURE_DECORATED_IDENTITY)); 3642 assertTrue(mWifiManager.isDecoratedIdentitySupported()); 3643 when(mWifiService.getSupportedFeatures()) 3644 .thenReturn(new Long(~WIFI_FEATURE_DECORATED_IDENTITY)); 3645 assertFalse(mWifiManager.isDecoratedIdentitySupported()); 3646 } 3647 3648 /** 3649 * Test behavior of isTrustOnFirstUseSupported. 3650 */ 3651 @Test testIsTrustOnFirstUseSupported()3652 public void testIsTrustOnFirstUseSupported() throws Exception { 3653 when(mWifiService.getSupportedFeatures()) 3654 .thenReturn(new Long(WIFI_FEATURE_TRUST_ON_FIRST_USE)); 3655 assertTrue(mWifiManager.isTrustOnFirstUseSupported()); 3656 when(mWifiService.getSupportedFeatures()) 3657 .thenReturn(new Long(~WIFI_FEATURE_TRUST_ON_FIRST_USE)); 3658 assertFalse(mWifiManager.isTrustOnFirstUseSupported()); 3659 } 3660 3661 /** 3662 * Verify call to getAllowedChannels goes to WifiServiceImpl 3663 */ 3664 @Test testGetAllowedChannels()3665 public void testGetAllowedChannels() throws Exception { 3666 assumeTrue(SdkLevel.isAtLeastS()); 3667 int band = WifiScanner.WIFI_BAND_24_5_6_GHZ; 3668 int mode = WifiAvailableChannel.OP_MODE_WIFI_AWARE 3669 | WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO 3670 | WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI; 3671 mWifiManager.getAllowedChannels(band, mode); 3672 verify(mWifiService).getUsableChannels(eq(band), eq(mode), 3673 eq(WifiAvailableChannel.FILTER_REGULATORY), eq(TEST_PACKAGE_NAME), any()); 3674 } 3675 3676 /** 3677 * Verify call to getUsableChannels goes to WifiServiceImpl 3678 */ 3679 @Test testGetUsableChannels()3680 public void testGetUsableChannels() throws Exception { 3681 assumeTrue(SdkLevel.isAtLeastS()); 3682 int band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; 3683 int mode = WifiAvailableChannel.OP_MODE_WIFI_AWARE 3684 | WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI; 3685 mWifiManager.getUsableChannels(band, mode); 3686 verify(mWifiService).getUsableChannels(eq(band), eq(mode), 3687 eq(WifiAvailableChannel.FILTER_CONCURRENCY 3688 | WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE), 3689 eq(TEST_PACKAGE_NAME), any()); 3690 } 3691 3692 /** 3693 * Verify an IllegalArgumentException is thrown if callback is not provided. 3694 */ 3695 @Test testRegisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullCallback()3696 public void testRegisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullCallback() { 3697 assumeTrue(SdkLevel.isAtLeastT()); 3698 try { 3699 mWifiManager.registerActiveCountryCodeChangedCallback( 3700 new HandlerExecutor(mHandler), null); 3701 fail("expected IllegalArgumentException"); 3702 } catch (IllegalArgumentException expected) { 3703 } 3704 } 3705 3706 /** 3707 * Verify an IllegalArgumentException is thrown if executor is null. 3708 */ 3709 @Test testRegisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullExecutor()3710 public void testRegisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullExecutor() { 3711 assumeTrue(SdkLevel.isAtLeastT()); 3712 try { 3713 mWifiManager.registerActiveCountryCodeChangedCallback(null, 3714 mActiveCountryCodeChangedCallback); 3715 fail("expected IllegalArgumentException"); 3716 } catch (IllegalArgumentException expected) { 3717 } 3718 } 3719 3720 /** 3721 * Verify an IllegalArgumentException is thrown if callback is not provided. 3722 */ 3723 @Test testUnregisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullCallback()3724 public void testUnregisterActiveCountryCodeChangedCallbackThrowsExceptionOnNullCallback() { 3725 assumeTrue(SdkLevel.isAtLeastT()); 3726 try { 3727 mWifiManager.unregisterActiveCountryCodeChangedCallback(null); 3728 fail("expected IllegalArgumentException"); 3729 } catch (IllegalArgumentException expected) { 3730 } 3731 } 3732 3733 /** 3734 * Verify the call to registerActiveCountryCodeChangedCallback goes to WifiServiceImpl. 3735 */ 3736 @Test testRegisterActiveCountryCodeChangedCallbackCallGoesToWifiServiceImpl()3737 public void testRegisterActiveCountryCodeChangedCallbackCallGoesToWifiServiceImpl() 3738 throws Exception { 3739 assumeTrue(SdkLevel.isAtLeastT()); 3740 mWifiManager.registerActiveCountryCodeChangedCallback(new HandlerExecutor(mHandler), 3741 mActiveCountryCodeChangedCallback); 3742 verify(mWifiService).registerDriverCountryCodeChangedListener( 3743 any(IOnWifiDriverCountryCodeChangedListener.Stub.class), anyString(), 3744 any() /* getAttributionTag(), nullable */); 3745 } 3746 3747 /** 3748 * Verify the call to unregisterActiveCountryCodeChangedCallback goes to WifiServiceImpl. 3749 */ 3750 @Test testUnregisterActiveCountryCodeChangedCallbackCallGoesToWifiServiceImpl()3751 public void testUnregisterActiveCountryCodeChangedCallbackCallGoesToWifiServiceImpl() 3752 throws Exception { 3753 assumeTrue(SdkLevel.isAtLeastT()); 3754 ArgumentCaptor<IOnWifiDriverCountryCodeChangedListener.Stub> listenerCaptor = 3755 ArgumentCaptor.forClass(IOnWifiDriverCountryCodeChangedListener.Stub.class); 3756 mWifiManager.registerActiveCountryCodeChangedCallback(new HandlerExecutor(mHandler), 3757 mActiveCountryCodeChangedCallback); 3758 verify(mWifiService).registerDriverCountryCodeChangedListener(listenerCaptor.capture(), 3759 anyString(), any() /* getAttributionTag(), nullable */); 3760 3761 mWifiManager.unregisterActiveCountryCodeChangedCallback( 3762 mActiveCountryCodeChangedCallback); 3763 verify(mWifiService).unregisterDriverCountryCodeChangedListener(listenerCaptor.getValue()); 3764 } 3765 3766 /* 3767 * Verify client-provided callback is being called through callback proxy 3768 */ 3769 @Test testDriverCountryCodeChangedCallbackProxyCallsOnActiveCountryCodeChanged()3770 public void testDriverCountryCodeChangedCallbackProxyCallsOnActiveCountryCodeChanged() 3771 throws Exception { 3772 assumeTrue(SdkLevel.isAtLeastT()); 3773 ArgumentCaptor<IOnWifiDriverCountryCodeChangedListener.Stub> listenerCaptor = 3774 ArgumentCaptor.forClass(IOnWifiDriverCountryCodeChangedListener.Stub.class); 3775 mWifiManager.registerActiveCountryCodeChangedCallback(new HandlerExecutor(mHandler), 3776 mActiveCountryCodeChangedCallback); 3777 verify(mWifiService).registerDriverCountryCodeChangedListener(listenerCaptor.capture(), 3778 anyString(), any() /* getAttributionTag(), nullable */); 3779 3780 listenerCaptor.getValue().onDriverCountryCodeChanged(TEST_COUNTRY_CODE); 3781 mLooper.dispatchAll(); 3782 verify(mActiveCountryCodeChangedCallback).onActiveCountryCodeChanged(TEST_COUNTRY_CODE); 3783 } 3784 3785 /* 3786 * Verify client-provided callback is being called through callback proxy 3787 */ 3788 @Test testDriverCountryCodeChangedCallbackProxyCallsOnCountryCodeInactiveWhenNull()3789 public void testDriverCountryCodeChangedCallbackProxyCallsOnCountryCodeInactiveWhenNull() 3790 throws Exception { 3791 assumeTrue(SdkLevel.isAtLeastT()); 3792 ArgumentCaptor<IOnWifiDriverCountryCodeChangedListener.Stub> listenerCaptor = 3793 ArgumentCaptor.forClass(IOnWifiDriverCountryCodeChangedListener.Stub.class); 3794 mWifiManager.registerActiveCountryCodeChangedCallback(new HandlerExecutor(mHandler), 3795 mActiveCountryCodeChangedCallback); 3796 verify(mWifiService).registerDriverCountryCodeChangedListener(listenerCaptor.capture(), 3797 anyString(), any() /* getAttributionTag(), nullable */); 3798 3799 listenerCaptor.getValue().onDriverCountryCodeChanged(null); 3800 mLooper.dispatchAll(); 3801 verify(mActiveCountryCodeChangedCallback).onCountryCodeInactive(); 3802 } 3803 3804 /** 3805 * Verify an IllegalArgumentException is thrown if callback is not provided. 3806 */ 3807 @Test registerLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullCallback()3808 public void registerLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullCallback() { 3809 assumeTrue(SdkLevel.isAtLeastT()); 3810 try { 3811 mWifiManager.registerLocalOnlyHotspotSoftApCallback( 3812 new HandlerExecutor(mHandler), null); 3813 fail("expected IllegalArgumentException"); 3814 } catch (IllegalArgumentException expected) { 3815 } 3816 } 3817 3818 /** 3819 * Verify an IllegalArgumentException is thrown if executor is null. 3820 */ 3821 @Test registerLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullExecutor()3822 public void registerLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullExecutor() { 3823 assumeTrue(SdkLevel.isAtLeastT()); 3824 try { 3825 mWifiManager.registerLocalOnlyHotspotSoftApCallback(null, mSoftApCallback); 3826 fail("expected IllegalArgumentException"); 3827 } catch (IllegalArgumentException expected) { 3828 } 3829 } 3830 3831 /** 3832 * Verify an IllegalArgumentException is thrown if callback is not provided. 3833 */ 3834 @Test unregisterLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullCallback()3835 public void unregisterLohsSoftApCallbackThrowsIllegalArgumentExceptionOnNullCallback() { 3836 assumeTrue(SdkLevel.isAtLeastT()); 3837 try { 3838 mWifiManager.unregisterLocalOnlyHotspotSoftApCallback(null); 3839 fail("expected IllegalArgumentException"); 3840 } catch (IllegalArgumentException expected) { 3841 } 3842 } 3843 3844 /** 3845 * Verify the call to registerLocalOnlyHotspotSoftApCallback goes to WifiServiceImpl. 3846 */ 3847 @Test registerLocalOnlyHotspotSoftApCallbackCallGoesToWifiServiceImpl()3848 public void registerLocalOnlyHotspotSoftApCallbackCallGoesToWifiServiceImpl() 3849 throws Exception { 3850 assumeTrue(SdkLevel.isAtLeastT()); 3851 mWifiManager.registerLocalOnlyHotspotSoftApCallback(new HandlerExecutor(mHandler), 3852 mSoftApCallback); 3853 verify(mWifiService).registerLocalOnlyHotspotSoftApCallback( 3854 any(ISoftApCallback.Stub.class), any(Bundle.class)); 3855 } 3856 3857 /** 3858 * Verify the call to unregisterLocalOnlyHotspotSoftApCallback goes to WifiServiceImpl. 3859 */ 3860 @Test unregisterLocalOnlyHotspotSoftApCallbackCallGoesToWifiServiceImpl()3861 public void unregisterLocalOnlyHotspotSoftApCallbackCallGoesToWifiServiceImpl() 3862 throws Exception { 3863 assumeTrue(SdkLevel.isAtLeastT()); 3864 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 3865 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 3866 mWifiManager.registerLocalOnlyHotspotSoftApCallback(new HandlerExecutor(mHandler), 3867 mSoftApCallback); 3868 verify(mWifiService).registerLocalOnlyHotspotSoftApCallback(callbackCaptor.capture(), 3869 any(Bundle.class)); 3870 3871 mWifiManager.unregisterLocalOnlyHotspotSoftApCallback(mSoftApCallback); 3872 verify(mWifiService).unregisterLocalOnlyHotspotSoftApCallback(eq(callbackCaptor.getValue()), 3873 any(Bundle.class)); 3874 } 3875 3876 /** 3877 * Verify lohs client-provided callback is being called through callback proxy. 3878 */ 3879 @Test softApCallbackProxyCallsCallbackForLohsRegister()3880 public void softApCallbackProxyCallsCallbackForLohsRegister() throws Exception { 3881 assumeTrue(SdkLevel.isAtLeastT()); 3882 WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"), 3883 TEST_AP_INSTANCES[0]); 3884 SoftApCapability testSoftApCapability = new SoftApCapability(0); 3885 // Prepare test info and clients 3886 initTestInfoAndAddToTestMap(1); 3887 List<WifiClient> clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0); 3888 3889 ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = 3890 ArgumentCaptor.forClass(ISoftApCallback.Stub.class); 3891 mWifiManager.registerLocalOnlyHotspotSoftApCallback( 3892 new HandlerExecutor(mHandler), mSoftApCallback); 3893 verify(mWifiService).registerLocalOnlyHotspotSoftApCallback(callbackCaptor.capture(), 3894 any(Bundle.class)); 3895 3896 SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0, 3897 TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME); 3898 callbackCaptor.getValue().onStateChanged(state); 3899 callbackCaptor.getValue().onConnectedClientsOrInfoChanged( 3900 (Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(), 3901 (Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true); 3902 callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); 3903 callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient, 3904 WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); 3905 3906 mLooper.dispatchAll(); 3907 ArgumentCaptor<SoftApState> softApStateCaptor = 3908 ArgumentCaptor.forClass(SoftApState.class); 3909 verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture()); 3910 assertEquals(state, softApStateCaptor.getValue()); 3911 3912 verify(mSoftApCallback).onConnectedClientsChanged(clientList); 3913 verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList); 3914 verify(mSoftApCallback).onInfoChanged(mTestApInfo1); 3915 verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) -> 3916 infos.contains(mTestApInfo1))); 3917 3918 verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); 3919 3920 verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient, 3921 WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); 3922 } 3923 3924 /* 3925 * Verify call to {@link WifiManager#isStaConcurrencyForMultiInternetSupported}. 3926 */ 3927 @Test testIsStaConcurrencyForMultiInternetSupported()3928 public void testIsStaConcurrencyForMultiInternetSupported() throws Exception { 3929 when(mWifiService.getSupportedFeatures()) 3930 .thenReturn(new Long(WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET)); 3931 assertTrue(mWifiManager.isStaConcurrencyForMultiInternetSupported()); 3932 when(mWifiService.getSupportedFeatures()) 3933 .thenReturn(new Long(~WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET)); 3934 assertFalse(mWifiManager.isStaConcurrencyForMultiInternetSupported()); 3935 } 3936 3937 /* 3938 * Verify call to {@link WifiManager#getStaConcurrencyForMultiInternetMode()}. 3939 */ 3940 @Test testGetStaConcurrencyForMultiInternetMode()3941 public void testGetStaConcurrencyForMultiInternetMode() throws Exception { 3942 final int mode = mWifiManager.getStaConcurrencyForMultiInternetMode(); 3943 verify(mWifiService).getStaConcurrencyForMultiInternetMode(); 3944 assertEquals(WifiManager.WIFI_MULTI_INTERNET_MODE_DISABLED, mode); 3945 } 3946 3947 /* 3948 * Verify call to {@link WifiManager#setStaConcurrencyForMultiInternetMode()}. 3949 */ 3950 @Test testSetStaConcurrencyForMultiInternetMode()3951 public void testSetStaConcurrencyForMultiInternetMode() throws Exception { 3952 mWifiManager.setStaConcurrencyForMultiInternetMode( 3953 WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP); 3954 verify(mWifiService).setStaConcurrencyForMultiInternetMode( 3955 WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP); 3956 } 3957 3958 /* 3959 * Verify call to {@link WifiManager#isDualBandSimultaneousSupported}. 3960 */ 3961 @Test testIsDualBandSimultaneousSupported()3962 public void testIsDualBandSimultaneousSupported() throws Exception { 3963 when(mWifiService.getSupportedFeatures()) 3964 .thenReturn(new Long(WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS)); 3965 assertTrue(mWifiManager.isDualBandSimultaneousSupported()); 3966 when(mWifiService.getSupportedFeatures()) 3967 .thenReturn(new Long(~WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS)); 3968 assertFalse(mWifiManager.isDualBandSimultaneousSupported()); 3969 } 3970 /* 3971 * Verify call to {@link WifiManager#isTidToLinkMappingSupported()} 3972 */ 3973 @Test testIsTidToLinkMappingSupported()3974 public void testIsTidToLinkMappingSupported() throws Exception { 3975 when(mWifiService.getSupportedFeatures()).thenReturn(WIFI_FEATURE_T2LM_NEGOTIATION); 3976 assertTrue(mWifiManager.isTidToLinkMappingNegotiationSupported()); 3977 when(mWifiService.getSupportedFeatures()).thenReturn(~WIFI_FEATURE_T2LM_NEGOTIATION); 3978 assertFalse(mWifiManager.isTidToLinkMappingNegotiationSupported()); 3979 } 3980 3981 /** 3982 * Verify call to 3983 * {@link WifiManager#reportCreateInterfaceImpact(int, boolean, Executor, BiConsumer)}. 3984 */ 3985 @Test testIsItPossibleToCreateInterface()3986 public void testIsItPossibleToCreateInterface() throws Exception { 3987 assumeTrue(SdkLevel.isAtLeastT()); 3988 3989 final int interfaceToCreate = WifiManager.WIFI_INTERFACE_TYPE_DIRECT; 3990 final boolean requireNewInterface = false; 3991 final boolean canCreate = true; 3992 final String packageName1 = "TestPackage1"; 3993 final String packageName2 = "TestPackage2"; 3994 final int[] interfaces = 3995 {WifiManager.WIFI_INTERFACE_TYPE_AP, WifiManager.WIFI_INTERFACE_TYPE_AWARE}; 3996 final String[] packagesForInterfaces = 3997 {TEST_PACKAGE_NAME, packageName1 + "," + packageName2}; 3998 final Set<WifiManager.InterfaceCreationImpact> interfacePairs = Set.of( 3999 new WifiManager.InterfaceCreationImpact(interfaces[0], 4000 new ArraySet<>(new String[]{TEST_PACKAGE_NAME})), 4001 new WifiManager.InterfaceCreationImpact(interfaces[1], 4002 new ArraySet<>(new String[]{packageName1, packageName2}))); 4003 when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); 4004 BiConsumer<Boolean, Set<WifiManager.InterfaceCreationImpact>> resultCallback = mock( 4005 BiConsumer.class); 4006 ArgumentCaptor<IInterfaceCreationInfoCallback.Stub> cbCaptor = ArgumentCaptor.forClass( 4007 IInterfaceCreationInfoCallback.Stub.class); 4008 ArgumentCaptor<Set<WifiManager.InterfaceCreationImpact>> resultCaptor = 4009 ArgumentCaptor.forClass(Set.class); 4010 4011 mWifiManager.reportCreateInterfaceImpact(interfaceToCreate, requireNewInterface, 4012 new SynchronousExecutor(), resultCallback); 4013 verify(mWifiService).reportCreateInterfaceImpact(eq(TEST_PACKAGE_NAME), 4014 eq(interfaceToCreate), eq(requireNewInterface), cbCaptor.capture()); 4015 cbCaptor.getValue().onResults(canCreate, interfaces, packagesForInterfaces); 4016 verify(resultCallback).accept(eq(canCreate), resultCaptor.capture()); 4017 assertEquals(interfacePairs, resultCaptor.getValue()); 4018 } 4019 4020 /** 4021 * Verify call to getChannelData goes to WifiServiceImpl 4022 */ 4023 @Test testChannelData()4024 public void testChannelData() throws Exception { 4025 assumeTrue(SdkLevel.isAtLeastT()); 4026 Consumer<List<Bundle>> resultsCallback = mock(Consumer.class); 4027 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4028 mWifiManager.getChannelData(executor, resultsCallback); 4029 verify(mWifiService).getChannelData(any(IListListener.Stub.class), eq(TEST_PACKAGE_NAME), 4030 any(Bundle.class)); 4031 } 4032 4033 /** 4034 * Verify call to {@link WifiManager#addQosPolicies(List, Executor, Consumer)}. 4035 */ 4036 @Test testAddQosPolicies()4037 public void testAddQosPolicies() throws Exception { 4038 assumeTrue(SdkLevel.isAtLeastU()); 4039 4040 final int policyId = 2; 4041 final int direction = QosPolicyParams.DIRECTION_DOWNLINK; 4042 final int userPriority = QosPolicyParams.USER_PRIORITY_VIDEO_LOW; 4043 final int ipVersion = QosPolicyParams.IP_VERSION_4; 4044 QosPolicyParams policyParams = new QosPolicyParams.Builder(policyId, direction) 4045 .setUserPriority(userPriority) 4046 .setIpVersion(ipVersion) 4047 .build(); 4048 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4049 Consumer<List<Integer>> resultsCallback = mock(Consumer.class); 4050 4051 mWifiManager.addQosPolicies(Arrays.asList(policyParams), executor, resultsCallback); 4052 verify(mWifiService).addQosPolicies(any(), any(), eq(TEST_PACKAGE_NAME), 4053 any(IListListener.Stub.class)); 4054 } 4055 4056 /** 4057 * Verify call to {@link WifiManager#removeQosPolicies(int[])} 4058 */ 4059 @Test testRemoveQosPolicies()4060 public void testRemoveQosPolicies() throws Exception { 4061 assumeTrue(SdkLevel.isAtLeastU()); 4062 final int[] policyIdList = new int[]{127, 128}; 4063 mWifiManager.removeQosPolicies(policyIdList); 4064 verify(mWifiService).removeQosPolicies(any(), eq(TEST_PACKAGE_NAME)); 4065 } 4066 4067 @Test testAddRemoveLocaOnlyConnectionListener()4068 public void testAddRemoveLocaOnlyConnectionListener() throws RemoteException { 4069 assertThrows(IllegalArgumentException.class, () -> mWifiManager 4070 .addLocalOnlyConnectionFailureListener(null, mLocalOnlyConnectionFailureListener)); 4071 assertThrows(IllegalArgumentException.class, () -> mWifiManager 4072 .addLocalOnlyConnectionFailureListener(mExecutor, null)); 4073 mWifiManager.addLocalOnlyConnectionFailureListener(mExecutor, 4074 mLocalOnlyConnectionFailureListener); 4075 verify(mWifiService).addLocalOnlyConnectionStatusListener(any(), eq(TEST_PACKAGE_NAME), 4076 nullable(String.class)); 4077 mWifiManager.removeLocalOnlyConnectionFailureListener(mLocalOnlyConnectionFailureListener); 4078 verify(mWifiService).removeLocalOnlyConnectionStatusListener(any(), eq(TEST_PACKAGE_NAME)); 4079 } 4080 4081 /** 4082 * Verify if the call for set / get link layer stats polling interval goes to WifiServiceImpl 4083 */ 4084 @Test testSetAndGetLinkLayerStatsPollingInterval()4085 public void testSetAndGetLinkLayerStatsPollingInterval() throws Exception { 4086 assumeTrue(SdkLevel.isAtLeastT()); 4087 mWifiManager.setLinkLayerStatsPollingInterval(TEST_LINK_LAYER_STATS_POLLING_INTERVAL_MS); 4088 verify(mWifiService).setLinkLayerStatsPollingInterval( 4089 eq(TEST_LINK_LAYER_STATS_POLLING_INTERVAL_MS)); 4090 4091 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4092 Consumer<Integer> resultsCallback = mock(Consumer.class); 4093 mWifiManager.getLinkLayerStatsPollingInterval(executor, resultsCallback); 4094 verify(mWifiService).getLinkLayerStatsPollingInterval(any(IIntegerListener.class)); 4095 4096 // null executor 4097 assertThrows(NullPointerException.class, 4098 () -> mWifiManager.getLinkLayerStatsPollingInterval(null, resultsCallback)); 4099 // null resultsCallback 4100 assertThrows(NullPointerException.class, 4101 () -> mWifiManager.getLinkLayerStatsPollingInterval(executor, null)); 4102 } 4103 4104 /** 4105 * Verify {@link WifiManager#setMloMode(int)} and {@link WifiManager#getMloMode()}. 4106 */ 4107 @Test testMloMode()4108 public void testMloMode() throws RemoteException { 4109 Consumer<Boolean> resultsSetCallback = mock(Consumer.class); 4110 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4111 // Out of range values. 4112 assertThrows(IllegalArgumentException.class, 4113 () -> mWifiManager.setMloMode(-1, executor, resultsSetCallback)); 4114 assertThrows(IllegalArgumentException.class, 4115 () -> mWifiManager.setMloMode(1000, executor, resultsSetCallback)); 4116 // Null executor/callback exception. 4117 assertThrows("null executor should trigger exception", NullPointerException.class, 4118 () -> mWifiManager.setMloMode(WifiManager.MLO_MODE_DEFAULT, null, 4119 resultsSetCallback)); 4120 assertThrows("null listener should trigger exception", NullPointerException.class, 4121 () -> mWifiManager.setMloMode(WifiManager.MLO_MODE_DEFAULT, executor, null)); 4122 // Set and verify. 4123 mWifiManager.setMloMode(WifiManager.MLO_MODE_LOW_POWER, executor, resultsSetCallback); 4124 verify(mWifiService).setMloMode(eq(WifiManager.MLO_MODE_LOW_POWER), 4125 any(IBooleanListener.Stub.class)); 4126 // Get and verify. 4127 Consumer<Integer> resultsGetCallback = mock(Consumer.class); 4128 mWifiManager.getMloMode(executor, resultsGetCallback); 4129 verify(mWifiService).getMloMode(any(IIntegerListener.Stub.class)); 4130 } 4131 4132 @Test testVerboseLogging()4133 public void testVerboseLogging() throws RemoteException { 4134 mWifiManager.setVerboseLoggingEnabled(true); 4135 verify(mWifiService).enableVerboseLogging(VERBOSE_LOGGING_LEVEL_ENABLED); 4136 mWifiManager.setVerboseLoggingEnabled(false); 4137 verify(mWifiService).enableVerboseLogging(VERBOSE_LOGGING_LEVEL_DISABLED); 4138 when(mWifiService.getVerboseLoggingLevel()).thenReturn(VERBOSE_LOGGING_LEVEL_ENABLED); 4139 assertTrue(mWifiManager.isVerboseLoggingEnabled()); 4140 when(mWifiService.getVerboseLoggingLevel()) 4141 .thenReturn(VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY); 4142 assertTrue(mWifiManager.isVerboseLoggingEnabled()); 4143 when(mWifiService.getVerboseLoggingLevel()) 4144 .thenReturn(VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY); 4145 assertFalse(mWifiManager.isVerboseLoggingEnabled()); 4146 when(mWifiService.getVerboseLoggingLevel()).thenReturn(VERBOSE_LOGGING_LEVEL_DISABLED); 4147 assertFalse(mWifiManager.isVerboseLoggingEnabled()); 4148 } 4149 4150 /** 4151 * Test behavior of isWepSupported 4152 */ 4153 @Test testIsWepSupported()4154 public void testIsWepSupported() throws Exception { 4155 when(mWifiService.getSupportedFeatures()) 4156 .thenReturn(new Long(WIFI_FEATURE_WEP)); 4157 assertTrue(mWifiManager.isWepSupported()); 4158 when(mWifiService.getSupportedFeatures()) 4159 .thenReturn(new Long(~WIFI_FEATURE_WEP)); 4160 assertFalse(mWifiManager.isWepSupported()); 4161 } 4162 4163 /** 4164 * Test behavior of isWpaPersonalSupported 4165 */ 4166 @Test testIsWpaPersonalSupported()4167 public void testIsWpaPersonalSupported() throws Exception { 4168 when(mWifiService.getSupportedFeatures()) 4169 .thenReturn(new Long(WIFI_FEATURE_WPA_PERSONAL)); 4170 assertTrue(mWifiManager.isWpaPersonalSupported()); 4171 when(mWifiService.getSupportedFeatures()) 4172 .thenReturn(new Long(~WIFI_FEATURE_WPA_PERSONAL)); 4173 assertFalse(mWifiManager.isWpaPersonalSupported()); 4174 } 4175 4176 @Test testSetWepAllowed()4177 public void testSetWepAllowed() throws Exception { 4178 mWifiManager.setWepAllowed(true); 4179 verify(mWifiService).setWepAllowed(true); 4180 mWifiManager.setWepAllowed(false); 4181 verify(mWifiService).setWepAllowed(false); 4182 } 4183 4184 @Test testQueryWepAllowed()4185 public void testQueryWepAllowed() throws Exception { 4186 Consumer<Boolean> resultsSetCallback = mock(Consumer.class); 4187 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4188 // Null executor/callback exception. 4189 assertThrows("null executor should trigger exception", NullPointerException.class, 4190 () -> mWifiManager.queryWepAllowed(null, resultsSetCallback)); 4191 assertThrows("null listener should trigger exception", NullPointerException.class, 4192 () -> mWifiManager.queryWepAllowed(executor, null)); 4193 // Set and verify. 4194 mWifiManager.queryWepAllowed(executor, resultsSetCallback); 4195 verify(mWifiService).queryWepAllowed( 4196 any(IBooleanListener.Stub.class)); 4197 } 4198 4199 /** 4200 * Verify {@link WifiManager#setPerSsidRoamingMode(WifiSsid, int)}. 4201 */ 4202 @Test testSetPerSsidRoamingMode()4203 public void testSetPerSsidRoamingMode() throws RemoteException { 4204 assumeTrue(SdkLevel.isAtLeastV()); 4205 // Invalid input throws exception. 4206 assertThrows(IllegalArgumentException.class, 4207 () -> mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), -1)); 4208 assertThrows(IllegalArgumentException.class, 4209 () -> mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), 3)); 4210 assertThrows(NullPointerException.class, 4211 () -> mWifiManager.setPerSsidRoamingMode(null, WifiManager.ROAMING_MODE_NORMAL)); 4212 // Set and verify. 4213 mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), 4214 WifiManager.ROAMING_MODE_NORMAL); 4215 verify(mWifiService).setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), 4216 WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME); 4217 } 4218 4219 /** 4220 * Verify {@link WifiManager#removePerSsidRoamingMode(WifiSsid)}. 4221 */ 4222 @Test testRemovePerSsidRoamingMode()4223 public void testRemovePerSsidRoamingMode() throws RemoteException { 4224 assumeTrue(SdkLevel.isAtLeastV()); 4225 // Invalid input throws exception. 4226 assertThrows(NullPointerException.class, 4227 () -> mWifiManager.removePerSsidRoamingMode(null)); 4228 // Remove and verify. 4229 mWifiManager.removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID)); 4230 verify(mWifiService).removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), 4231 TEST_PACKAGE_NAME); 4232 } 4233 4234 /** 4235 * Verify {@link WifiManager#getPerSsidRoamingModes()}. 4236 */ 4237 @Test testGetPerSsidRoamingModes()4238 public void testGetPerSsidRoamingModes() throws RemoteException { 4239 assumeTrue(SdkLevel.isAtLeastV()); 4240 Consumer<Map<String, Integer>> resultsSetCallback = mock(Consumer.class); 4241 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4242 // Null executor/callback exception. 4243 assertThrows("null executor should trigger exception", NullPointerException.class, 4244 () -> mWifiManager.getPerSsidRoamingModes(null, 4245 resultsSetCallback)); 4246 assertThrows("null executor should trigger exception", NullPointerException.class, 4247 () -> mWifiManager.getPerSsidRoamingModes(executor, 4248 null)); 4249 // Get and verify. 4250 mWifiManager.getPerSsidRoamingModes(executor, resultsSetCallback); 4251 verify(mWifiService).getPerSsidRoamingModes(eq(TEST_PACKAGE_NAME), 4252 any(IMapListener.Stub.class)); 4253 } 4254 4255 @Test testGetTwtCapabilities()4256 public void testGetTwtCapabilities() throws Exception { 4257 assumeTrue(SdkLevel.isAtLeastV()); 4258 Consumer<Bundle> resultCallback = mock(Consumer.class); 4259 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4260 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 4261 // Null check 4262 assertThrows("null executor should trigger exception", NullPointerException.class, 4263 () -> mWifiManager.getTwtCapabilities(executor, null)); 4264 assertThrows("null executor should trigger exception", NullPointerException.class, 4265 () -> mWifiManager.getTwtCapabilities(null, resultCallback)); 4266 // Get and verify 4267 mWifiManager.getTwtCapabilities(executor, resultCallback); 4268 verify(mWifiService).getTwtCapabilities(any(ITwtCapabilitiesListener.Stub.class), 4269 bundleCaptor.capture()); 4270 verify(mContext.getAttributionSource()).equals( 4271 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 4272 } 4273 4274 @Test testSetupTwtSession()4275 public void testSetupTwtSession() throws Exception { 4276 assumeTrue(SdkLevel.isAtLeastV()); 4277 TwtSessionCallback resultCallback = mock(TwtSessionCallback.class); 4278 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4279 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 4280 TwtRequest twtRequest = mock(TwtRequest.class); 4281 // Null check 4282 assertThrows("null executor should trigger exception", NullPointerException.class, 4283 () -> mWifiManager.setupTwtSession(null, executor, resultCallback)); 4284 assertThrows("null executor should trigger exception", NullPointerException.class, 4285 () -> mWifiManager.setupTwtSession(twtRequest, null, resultCallback)); 4286 assertThrows("null executor should trigger exception", NullPointerException.class, 4287 () -> mWifiManager.setupTwtSession(twtRequest, executor, null)); 4288 // Call twtSessionSetup and verify 4289 mWifiManager.setupTwtSession(twtRequest, executor, resultCallback); 4290 verify(mWifiService).setupTwtSession(any(TwtRequest.class), any(ITwtCallback.class), 4291 bundleCaptor.capture()); 4292 verify(mContext.getAttributionSource()).equals( 4293 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 4294 } 4295 4296 @Test testGetStatsTwtSession()4297 public void testGetStatsTwtSession() throws Exception { 4298 assumeTrue(SdkLevel.isAtLeastV()); 4299 Consumer<Bundle> resultCallback = mock(Consumer.class); 4300 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4301 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 4302 // Null check 4303 assertThrows("null executor should trigger exception", NullPointerException.class, 4304 () -> mWifiManager.getStatsTwtSession(0, null, resultCallback)); 4305 assertThrows("null executor should trigger exception", NullPointerException.class, 4306 () -> mWifiManager.getStatsTwtSession(0, executor, null)); 4307 // Call twtSessionGetStats and verify 4308 mWifiManager.getStatsTwtSession(2, executor, resultCallback); 4309 verify(mWifiService).getStatsTwtSession(eq(2), any(ITwtStatsListener.class), 4310 bundleCaptor.capture()); 4311 verify(mContext.getAttributionSource()).equals( 4312 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 4313 } 4314 4315 @Test testTeardownTwtSession()4316 public void testTeardownTwtSession() throws Exception { 4317 assumeTrue(SdkLevel.isAtLeastV()); 4318 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 4319 // Call twtSessionTeardown and verify 4320 mWifiManager.teardownTwtSession(10); 4321 verify(mWifiService).teardownTwtSession(eq(10), bundleCaptor.capture()); 4322 verify(mContext.getAttributionSource()).equals( 4323 bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 4324 } 4325 4326 /** 4327 * Test behavior of isD2dSupportedWhenInfraStaDisabled. 4328 */ 4329 @Test testIsD2dSupportedWhenInfraStaDisabled()4330 public void testIsD2dSupportedWhenInfraStaDisabled() throws Exception { 4331 when(mWifiService.getSupportedFeatures()) 4332 .thenReturn(new Long(WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED)); 4333 assertTrue(mWifiManager.isD2dSupportedWhenInfraStaDisabled()); 4334 when(mWifiService.getSupportedFeatures()) 4335 .thenReturn(new Long(~WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED)); 4336 assertFalse(mWifiManager.isD2dSupportedWhenInfraStaDisabled()); 4337 } 4338 4339 @Test testSetD2dAllowedInfraStaDisabled()4340 public void testSetD2dAllowedInfraStaDisabled() throws Exception { 4341 mWifiManager.setD2dAllowedWhenInfraStaDisabled(true); 4342 verify(mWifiService).setD2dAllowedWhenInfraStaDisabled(true); 4343 mWifiManager.setD2dAllowedWhenInfraStaDisabled(false); 4344 verify(mWifiService).setD2dAllowedWhenInfraStaDisabled(false); 4345 } 4346 4347 @Test testQueryD2dAllowedInfraStaDisabled()4348 public void testQueryD2dAllowedInfraStaDisabled() throws Exception { 4349 Consumer<Boolean> resultsSetCallback = mock(Consumer.class); 4350 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4351 // Null executor/callback exception. 4352 assertThrows("null executor should trigger exception", NullPointerException.class, 4353 () -> mWifiManager.queryD2dAllowedWhenInfraStaDisabled(null, resultsSetCallback)); 4354 assertThrows("null listener should trigger exception", NullPointerException.class, 4355 () -> mWifiManager.queryD2dAllowedWhenInfraStaDisabled(executor, null)); 4356 // Set and verify. 4357 mWifiManager.queryD2dAllowedWhenInfraStaDisabled(executor, resultsSetCallback); 4358 verify(mWifiService).queryD2dAllowedWhenInfraStaDisabled( 4359 any(IBooleanListener.Stub.class)); 4360 } 4361 4362 @Test testRetrieveRestoreWifiBackupData()4363 public void testRetrieveRestoreWifiBackupData() throws Exception { 4364 assumeTrue(SdkLevel.isAtLeastV()); 4365 Consumer<byte[]> resultsSetCallback = mock(Consumer.class); 4366 SynchronousExecutor executor = mock(SynchronousExecutor.class); 4367 byte[] testByteArray = new byte[0]; 4368 // Null executor/callback exception. 4369 assertThrows("null executor should trigger exception", NullPointerException.class, 4370 () -> mWifiManager.retrieveWifiBackupData(null, resultsSetCallback)); 4371 assertThrows("null listener should trigger exception", NullPointerException.class, 4372 () -> mWifiManager.retrieveWifiBackupData(executor, null)); 4373 // Call and verify. 4374 mWifiManager.retrieveWifiBackupData(executor, resultsSetCallback); 4375 verify(mWifiService).retrieveWifiBackupData( 4376 any(IByteArrayListener.Stub.class)); 4377 mWifiManager.restoreWifiBackupData(testByteArray); 4378 verify(mWifiService).restoreWifiBackupData(eq(testByteArray)); 4379 } 4380 4381 4382 @Test testIsPreferredNetworkOffloadSupported()4383 public void testIsPreferredNetworkOffloadSupported() throws Exception { 4384 mWifiManager.isPreferredNetworkOffloadSupported(); 4385 verify(mWifiService).isPnoSupported(); 4386 } 4387 } 4388