1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi.hotspot2; 18 19 import static android.app.AppOpsManager.MODE_IGNORED; 20 import static android.app.AppOpsManager.OPSTR_CHANGE_WIFI_STATE; 21 22 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertNull; 27 import static org.junit.Assert.assertThat; 28 import static org.junit.Assert.assertTrue; 29 import static org.mockito.ArgumentMatchers.isNull; 30 import static org.mockito.Mockito.any; 31 import static org.mockito.Mockito.anyBoolean; 32 import static org.mockito.Mockito.anyInt; 33 import static org.mockito.Mockito.anyLong; 34 import static org.mockito.Mockito.anyMap; 35 import static org.mockito.Mockito.doThrow; 36 import static org.mockito.Mockito.eq; 37 import static org.mockito.Mockito.lenient; 38 import static org.mockito.Mockito.mock; 39 import static org.mockito.Mockito.never; 40 import static org.mockito.Mockito.reset; 41 import static org.mockito.Mockito.verify; 42 import static org.mockito.Mockito.when; 43 import static org.mockito.MockitoAnnotations.initMocks; 44 45 import android.app.AppOpsManager; 46 import android.content.Context; 47 import android.content.Intent; 48 import android.net.Uri; 49 import android.net.wifi.EAPConstants; 50 import android.net.wifi.ScanResult; 51 import android.net.wifi.WifiConfiguration; 52 import android.net.wifi.WifiEnterpriseConfig; 53 import android.net.wifi.WifiManager; 54 import android.net.wifi.WifiSsid; 55 import android.net.wifi.hotspot2.IProvisioningCallback; 56 import android.net.wifi.hotspot2.OsuProvider; 57 import android.net.wifi.hotspot2.PasspointConfiguration; 58 import android.net.wifi.hotspot2.pps.Credential; 59 import android.net.wifi.hotspot2.pps.HomeSp; 60 import android.os.Handler; 61 import android.os.Looper; 62 import android.os.UserHandle; 63 import android.os.test.TestLooper; 64 import android.telephony.SubscriptionManager; 65 import android.telephony.TelephonyManager; 66 import android.util.Base64; 67 import android.util.Pair; 68 69 import androidx.test.filters.SmallTest; 70 71 import com.android.dx.mockito.inline.extended.ExtendedMockito; 72 import com.android.server.wifi.ClientModeImpl; 73 import com.android.server.wifi.Clock; 74 import com.android.server.wifi.FakeKeys; 75 import com.android.server.wifi.IMSIParameter; 76 import com.android.server.wifi.SIMAccessor; 77 import com.android.server.wifi.ScanDetail; 78 import com.android.server.wifi.WifiConfigManager; 79 import com.android.server.wifi.WifiConfigStore; 80 import com.android.server.wifi.WifiConfigurationTestUtil; 81 import com.android.server.wifi.WifiInjector; 82 import com.android.server.wifi.WifiKeyStore; 83 import com.android.server.wifi.WifiMetrics; 84 import com.android.server.wifi.WifiNative; 85 import com.android.server.wifi.hotspot2.anqp.ANQPElement; 86 import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; 87 import com.android.server.wifi.hotspot2.anqp.DomainNameElement; 88 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement; 89 import com.android.server.wifi.hotspot2.anqp.I18Name; 90 import com.android.server.wifi.hotspot2.anqp.NAIRealmData; 91 import com.android.server.wifi.hotspot2.anqp.NAIRealmElement; 92 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo; 93 import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod; 94 import com.android.server.wifi.util.InformationElementUtil; 95 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium; 96 97 import org.junit.Before; 98 import org.junit.Test; 99 import org.mockito.ArgumentCaptor; 100 import org.mockito.Mock; 101 import org.mockito.MockitoSession; 102 103 import java.nio.charset.StandardCharsets; 104 import java.security.GeneralSecurityException; 105 import java.security.KeyStore; 106 import java.security.cert.X509Certificate; 107 import java.util.ArrayList; 108 import java.util.Arrays; 109 import java.util.HashMap; 110 import java.util.HashSet; 111 import java.util.List; 112 import java.util.Locale; 113 import java.util.Map; 114 import java.util.Set; 115 116 /** 117 * Unit tests for {@link PasspointManager}. 118 */ 119 @SmallTest 120 public class PasspointManagerTest { 121 private static final long BSSID = 0x112233445566L; 122 private static final String TEST_PACKAGE = "com.android.test"; 123 private static final String TEST_FQDN = "test1.test.com"; 124 private static final String TEST_FQDN2 = "test2.test.com"; 125 private static final String TEST_FRIENDLY_NAME = "friendly name"; 126 private static final String TEST_FRIENDLY_NAME2 = "second friendly name"; 127 private static final String TEST_REALM = "realm.test.com"; 128 private static final String TEST_IMSI = "123456*"; 129 private static final IMSIParameter TEST_IMSI_PARAM = IMSIParameter.build(TEST_IMSI); 130 131 private static final long TEST_BSSID = 0x112233445566L; 132 private static final String TEST_SSID = "TestSSID"; 133 private static final String TEST_BSSID_STRING = "11:22:33:44:55:66"; 134 private static final String TEST_SSID2 = "TestSSID2"; 135 private static final String TEST_BSSID_STRING2 = "11:22:33:44:55:77"; 136 private static final String TEST_SSID3 = "TestSSID3"; 137 private static final String TEST_BSSID_STRING3 = "11:22:33:44:55:88"; 138 private static final String TEST_MCC_MNC = "123456"; 139 private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org", 140 TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3)); 141 142 private static final long TEST_HESSID = 0x5678L; 143 private static final int TEST_ANQP_DOMAIN_ID = 0; 144 private static final int TEST_ANQP_DOMAIN_ID2 = 1; 145 private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey( 146 TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID); 147 private static final ANQPNetworkKey TEST_ANQP_KEY2 = ANQPNetworkKey.buildKey( 148 TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID2); 149 private static final int TEST_CREATOR_UID = 1234; 150 private static final int TEST_UID = 1500; 151 152 @Mock Context mContext; 153 @Mock WifiNative mWifiNative; 154 @Mock WifiKeyStore mWifiKeyStore; 155 @Mock Clock mClock; 156 @Mock SIMAccessor mSimAccessor; 157 @Mock PasspointObjectFactory mObjectFactory; 158 @Mock PasspointEventHandler.Callbacks mCallbacks; 159 @Mock AnqpCache mAnqpCache; 160 @Mock ANQPRequestManager mAnqpRequestManager; 161 @Mock CertificateVerifier mCertVerifier; 162 @Mock WifiConfigManager mWifiConfigManager; 163 @Mock WifiConfigStore mWifiConfigStore; 164 @Mock PasspointConfigSharedStoreData.DataSource mSharedDataSource; 165 @Mock PasspointConfigUserStoreData.DataSource mUserDataSource; 166 @Mock WifiMetrics mWifiMetrics; 167 @Mock OsuNetworkConnection mOsuNetworkConnection; 168 @Mock OsuServerConnection mOsuServerConnection; 169 @Mock PasspointProvisioner mPasspointProvisioner; 170 @Mock IProvisioningCallback mCallback; 171 @Mock WfaKeyStore mWfaKeyStore; 172 @Mock KeyStore mKeyStore; 173 @Mock AppOpsManager mAppOpsManager; 174 @Mock WifiInjector mWifiInjector; 175 @Mock ClientModeImpl mClientModeImpl; 176 @Mock TelephonyManager mTelephonyManager; 177 @Mock TelephonyManager mDataTelephonyManager; 178 @Mock SubscriptionManager mSubscriptionManager; 179 180 Handler mHandler; 181 TestLooper mLooper; 182 PasspointManager mManager; 183 ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor = 184 ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class); 185 186 /** Sets up test. */ 187 @Before setUp()188 public void setUp() throws Exception { 189 initMocks(this); 190 when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache); 191 when(mObjectFactory.makeANQPRequestManager(any(), eq(mClock))) 192 .thenReturn(mAnqpRequestManager); 193 when(mObjectFactory.makeCertificateVerifier()).thenReturn(mCertVerifier); 194 when(mObjectFactory.makeOsuNetworkConnection(any(Context.class))) 195 .thenReturn(mOsuNetworkConnection); 196 when(mObjectFactory.makeOsuServerConnection()) 197 .thenReturn(mOsuServerConnection); 198 when(mObjectFactory.makeWfaKeyStore()).thenReturn(mWfaKeyStore); 199 when(mWfaKeyStore.get()).thenReturn(mKeyStore); 200 when(mObjectFactory.makePasspointProvisioner(any(Context.class), any(WifiNative.class), 201 any(PasspointManager.class), any(WifiMetrics.class))) 202 .thenReturn(mPasspointProvisioner); 203 when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); 204 when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl); 205 mLooper = new TestLooper(); 206 mHandler = new Handler(mLooper.getLooper()); 207 mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative, 208 mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, mWifiConfigManager, 209 mWifiConfigStore, mWifiMetrics, mTelephonyManager, mSubscriptionManager); 210 ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks = 211 ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class); 212 verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class), 213 callbacks.capture()); 214 ArgumentCaptor<PasspointConfigSharedStoreData.DataSource> sharedDataSource = 215 ArgumentCaptor.forClass(PasspointConfigSharedStoreData.DataSource.class); 216 verify(mObjectFactory).makePasspointConfigSharedStoreData(sharedDataSource.capture()); 217 ArgumentCaptor<PasspointConfigUserStoreData.DataSource> userDataSource = 218 ArgumentCaptor.forClass(PasspointConfigUserStoreData.DataSource.class); 219 verify(mObjectFactory).makePasspointConfigUserStoreData( 220 any(WifiKeyStore.class), any(SIMAccessor.class), userDataSource.capture()); 221 mCallbacks = callbacks.getValue(); 222 mSharedDataSource = sharedDataSource.getValue(); 223 mUserDataSource = userDataSource.getValue(); 224 // SIM is absent 225 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]); 226 } 227 228 /** 229 * Verify that the given Passpoint configuration matches the one that's added to 230 * the PasspointManager. 231 * 232 * @param expectedConfig The expected installed Passpoint configuration 233 */ verifyInstalledConfig(PasspointConfiguration expectedConfig)234 private void verifyInstalledConfig(PasspointConfiguration expectedConfig) { 235 List<PasspointConfiguration> installedConfigs = mManager.getProviderConfigs(); 236 assertEquals(1, installedConfigs.size()); 237 assertEquals(expectedConfig, installedConfigs.get(0)); 238 } 239 240 /** 241 * Create a mock PasspointProvider with default expectations. 242 * 243 * @param config The configuration associated with the provider 244 * @return {@link com.android.server.wifi.hotspot2.PasspointProvider} 245 */ createMockProvider(PasspointConfiguration config)246 private PasspointProvider createMockProvider(PasspointConfiguration config) { 247 PasspointProvider provider = mock(PasspointProvider.class); 248 when(provider.installCertsAndKeys()).thenReturn(true); 249 lenient().when(provider.getConfig()).thenReturn(config); 250 return provider; 251 } 252 253 /** 254 * Helper function for creating a test configuration with user credential. 255 * 256 * @return {@link PasspointConfiguration} 257 */ createTestConfigWithUserCredential(String fqdn, String friendlyName)258 private PasspointConfiguration createTestConfigWithUserCredential(String fqdn, 259 String friendlyName) { 260 PasspointConfiguration config = new PasspointConfiguration(); 261 HomeSp homeSp = new HomeSp(); 262 homeSp.setFqdn(fqdn); 263 homeSp.setFriendlyName(friendlyName); 264 config.setHomeSp(homeSp); 265 Map<String, String> friendlyNames = new HashMap<>(); 266 friendlyNames.put("en", friendlyName); 267 friendlyNames.put("kr", friendlyName + 1); 268 friendlyNames.put("jp", friendlyName + 2); 269 config.setServiceFriendlyNames(friendlyNames); 270 Credential credential = new Credential(); 271 credential.setRealm(TEST_REALM); 272 credential.setCaCertificate(FakeKeys.CA_CERT0); 273 Credential.UserCredential userCredential = new Credential.UserCredential(); 274 userCredential.setUsername("username"); 275 userCredential.setPassword("password"); 276 userCredential.setEapType(EAPConstants.EAP_TTLS); 277 userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAP); 278 credential.setUserCredential(userCredential); 279 config.setCredential(credential); 280 return config; 281 } 282 283 /** 284 * Helper function for creating a test configuration with SIM credential. 285 * 286 * @return {@link PasspointConfiguration} 287 */ createTestConfigWithSimCredential(String fqdn, String imsi, String realm)288 private PasspointConfiguration createTestConfigWithSimCredential(String fqdn, String imsi, 289 String realm) { 290 PasspointConfiguration config = new PasspointConfiguration(); 291 HomeSp homeSp = new HomeSp(); 292 homeSp.setFqdn(fqdn); 293 homeSp.setFriendlyName(TEST_FRIENDLY_NAME); 294 config.setHomeSp(homeSp); 295 Credential credential = new Credential(); 296 credential.setRealm(TEST_REALM); 297 Credential.SimCredential simCredential = new Credential.SimCredential(); 298 simCredential.setImsi(imsi); 299 simCredential.setEapType(EAPConstants.EAP_SIM); 300 credential.setSimCredential(simCredential); 301 config.setCredential(credential); 302 return config; 303 } 304 305 /** 306 * Helper function for adding a test provider to the manager. Return the mock 307 * provider that's added to the manager. 308 * 309 * @return {@link PasspointProvider} 310 */ addTestProvider(String fqdn, String friendlyName, String packageName)311 private PasspointProvider addTestProvider(String fqdn, String friendlyName, 312 String packageName) { 313 PasspointConfiguration config = createTestConfigWithUserCredential(fqdn, friendlyName); 314 PasspointProvider provider = createMockProvider(config); 315 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 316 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 317 provider); 318 when(provider.getPackageName()).thenReturn(packageName); 319 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 320 return provider; 321 } 322 323 /** 324 * Helper function for adding a test provider with SIM credentials to the manager. Return the 325 * mock provider that's added to the manager. 326 * 327 * @return {@link PasspointProvider} 328 */ addTestCarrierProvider(String fqdn, String imsi, String realm)329 private PasspointProvider addTestCarrierProvider(String fqdn, String imsi, String realm) { 330 PasspointConfiguration config = createTestConfigWithSimCredential(fqdn, imsi, realm); 331 PasspointProvider provider = createMockProvider(config); 332 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 333 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 334 provider); 335 336 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 337 338 return provider; 339 } 340 341 /** 342 * Helper function for creating a ScanResult for testing. 343 * 344 * @return {@link ScanResult} 345 */ createTestScanResult()346 private ScanResult createTestScanResult() { 347 ScanResult scanResult = new ScanResult(); 348 scanResult.SSID = TEST_SSID; 349 scanResult.BSSID = TEST_BSSID_STRING; 350 scanResult.hessid = TEST_HESSID; 351 scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID; 352 scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 353 return scanResult; 354 } 355 356 /** 357 * Helper function for creating a ScanResult for testing. 358 * 359 * @return {@link ScanResult} 360 */ createTestScanResults()361 private List<ScanResult> createTestScanResults() { 362 List<ScanResult> scanResults = new ArrayList<>(); 363 364 // Passpoint AP 365 ScanResult scanResult = new ScanResult(); 366 scanResult.SSID = TEST_SSID; 367 scanResult.BSSID = TEST_BSSID_STRING; 368 scanResult.hessid = TEST_HESSID; 369 scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 370 scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID2; 371 scanResults.add(scanResult); 372 373 // Non-Passpoint AP 374 ScanResult scanResult2 = new ScanResult(); 375 scanResult2.SSID = TEST_SSID2; 376 scanResult2.BSSID = TEST_BSSID_STRING2; 377 scanResult2.hessid = TEST_HESSID; 378 scanResult2.flags = 0; 379 scanResults.add(scanResult2); 380 381 // Passpoint AP 382 ScanResult scanResult3 = new ScanResult(); 383 scanResult3.SSID = TEST_SSID3; 384 scanResult3.BSSID = TEST_BSSID_STRING3; 385 scanResult3.hessid = TEST_HESSID; 386 scanResult3.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 387 scanResult3.anqpDomainId = TEST_ANQP_DOMAIN_ID2; 388 scanResults.add(scanResult3); 389 390 return scanResults; 391 } 392 393 /** 394 * Helper function for generating {@link ScanDetail} for testing. 395 */ generateScanDetail(String ssid, String bssid, long hessid, int anqpDomaiId, boolean isPasspoint)396 private ScanDetail generateScanDetail(String ssid, String bssid, long hessid, int anqpDomaiId, 397 boolean isPasspoint) { 398 NetworkDetail networkDetail = mock(NetworkDetail.class); 399 400 ScanDetail scanDetail = mock(ScanDetail.class); 401 ScanResult scanResult = new ScanResult(); 402 scanResult.SSID = ssid; 403 scanResult.BSSID = bssid; 404 scanResult.hessid = hessid; 405 scanResult.anqpDomainId = anqpDomaiId; 406 if (isPasspoint) { 407 lenient().when(networkDetail.isInterworking()).thenReturn(true); 408 scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 409 } else { 410 lenient().when(networkDetail.isInterworking()).thenReturn(false); 411 } 412 413 lenient().when(scanDetail.getScanResult()).thenReturn(scanResult); 414 lenient().when(scanDetail.getNetworkDetail()).thenReturn(networkDetail); 415 return scanDetail; 416 } 417 418 /** 419 * Verify that the ANQP elements will be added to the ANQP cache on receiving a successful 420 * response. 421 * 422 * @throws Exception 423 */ 424 @Test anqpResponseSuccess()425 public void anqpResponseSuccess() throws Exception { 426 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 427 anqpElementMap.put(ANQPElementType.ANQPDomName, 428 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 429 430 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY); 431 mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); 432 verify(mAnqpCache).addEntry(TEST_ANQP_KEY, anqpElementMap); 433 verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), 434 any(String.class)); 435 } 436 437 /** 438 * Verify that no ANQP elements will be added to the ANQP cache on receiving a successful 439 * response for a request that's not sent by us. 440 * 441 * @throws Exception 442 */ 443 @Test anqpResponseSuccessWithUnknownRequest()444 public void anqpResponseSuccessWithUnknownRequest() throws Exception { 445 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 446 anqpElementMap.put(ANQPElementType.ANQPDomName, 447 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 448 449 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null); 450 mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); 451 verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap()); 452 } 453 454 /** 455 * Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response. 456 * 457 * @throws Exception 458 */ 459 @Test anqpResponseFailure()460 public void anqpResponseFailure() throws Exception { 461 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY); 462 mCallbacks.onANQPResponse(TEST_BSSID, null); 463 verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap()); 464 465 } 466 467 /** 468 * Verify that adding a provider with a null configuration will fail. 469 * 470 * @throws Exception 471 */ 472 @Test addProviderWithNullConfig()473 public void addProviderWithNullConfig() throws Exception { 474 assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE)); 475 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 476 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 477 } 478 479 /** 480 * Verify that adding a provider with a empty configuration will fail. 481 * 482 * @throws Exception 483 */ 484 @Test addProviderWithEmptyConfig()485 public void addProviderWithEmptyConfig() throws Exception { 486 assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID, 487 TEST_PACKAGE)); 488 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 489 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 490 } 491 492 /** 493 * Verify taht adding a provider with an invalid credential will fail (using EAP-TLS 494 * for user credential). 495 * 496 * @throws Exception 497 */ 498 @Test addProviderWithInvalidCredential()499 public void addProviderWithInvalidCredential() throws Exception { 500 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 501 TEST_FRIENDLY_NAME); 502 // EAP-TLS not allowed for user credential. 503 config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS); 504 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 505 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 506 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 507 } 508 509 /** 510 * Verify that adding a provider with a valid configuration and user credential will succeed. 511 * 512 * @throws Exception 513 */ 514 @Test addRemoveProviderWithValidUserCredential()515 public void addRemoveProviderWithValidUserCredential() throws Exception { 516 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 517 TEST_FRIENDLY_NAME); 518 PasspointProvider provider = createMockProvider(config); 519 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 520 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 521 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 522 provider); 523 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 524 verifyInstalledConfig(config); 525 verify(mWifiConfigManager).saveToStore(true); 526 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 527 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 528 verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), any( 529 AppOpsManager.OnOpChangedListener.class)); 530 reset(mWifiMetrics); 531 reset(mWifiConfigManager); 532 533 // Verify content in the data source. 534 List<PasspointProvider> providers = mUserDataSource.getProviders(); 535 assertEquals(1, providers.size()); 536 assertEquals(config, providers.get(0).getConfig()); 537 // Provider index start with 0, should be 1 after adding a provider. 538 assertEquals(1, mSharedDataSource.getProviderIndex()); 539 540 // Remove the provider. 541 assertTrue(mManager.removeProvider(TEST_FQDN)); 542 verify(provider).uninstallCertsAndKeys(); 543 verify(mWifiConfigManager).saveToStore(true); 544 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 545 verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); 546 verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class)); 547 assertTrue(mManager.getProviderConfigs().isEmpty()); 548 549 // Verify content in the data source. 550 assertTrue(mUserDataSource.getProviders().isEmpty()); 551 // Removing a provider should not change the provider index. 552 assertEquals(1, mSharedDataSource.getProviderIndex()); 553 } 554 555 /** 556 * Verify that adding a provider with a valid configuration and SIM credential will succeed. 557 * 558 * @throws Exception 559 */ 560 @Test addRemoveProviderWithValidSimCredential()561 public void addRemoveProviderWithValidSimCredential() throws Exception { 562 PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 563 TEST_REALM); 564 PasspointProvider provider = createMockProvider(config); 565 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 566 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 567 provider); 568 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 569 verifyInstalledConfig(config); 570 verify(mWifiConfigManager).saveToStore(true); 571 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 572 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 573 reset(mWifiMetrics); 574 reset(mWifiConfigManager); 575 576 // Verify content in the data source. 577 List<PasspointProvider> providers = mUserDataSource.getProviders(); 578 assertEquals(1, providers.size()); 579 assertEquals(config, providers.get(0).getConfig()); 580 // Provider index start with 0, should be 1 after adding a provider. 581 assertEquals(1, mSharedDataSource.getProviderIndex()); 582 583 // Remove the provider. 584 assertTrue(mManager.removeProvider(TEST_FQDN)); 585 verify(provider).uninstallCertsAndKeys(); 586 verify(mWifiConfigManager).saveToStore(true); 587 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 588 verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); 589 assertTrue(mManager.getProviderConfigs().isEmpty()); 590 591 // Verify content in the data source. 592 assertTrue(mUserDataSource.getProviders().isEmpty()); 593 // Removing a provider should not change the provider index. 594 assertEquals(1, mSharedDataSource.getProviderIndex()); 595 } 596 597 /** 598 * Verify that adding a provider with the same base domain as the existing provider will 599 * succeed, and verify that the existing provider is replaced by the new provider with 600 * the new configuration. 601 * 602 * @throws Exception 603 */ 604 @Test addProviderWithExistingConfig()605 public void addProviderWithExistingConfig() throws Exception { 606 // Add a provider with the original configuration. 607 PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 608 TEST_REALM); 609 PasspointProvider origProvider = createMockProvider(origConfig); 610 when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore), 611 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 612 origProvider); 613 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE)); 614 verifyInstalledConfig(origConfig); 615 verify(mWifiConfigManager).saveToStore(true); 616 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 617 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 618 reset(mWifiMetrics); 619 reset(mWifiConfigManager); 620 621 // Verify data source content. 622 List<PasspointProvider> origProviders = mUserDataSource.getProviders(); 623 assertEquals(1, origProviders.size()); 624 assertEquals(origConfig, origProviders.get(0).getConfig()); 625 assertEquals(1, mSharedDataSource.getProviderIndex()); 626 627 // Add another provider with the same base domain as the existing provider. 628 // This should replace the existing provider with the new configuration. 629 PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN, 630 TEST_FRIENDLY_NAME); 631 PasspointProvider newProvider = createMockProvider(newConfig); 632 when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore), 633 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 634 newProvider); 635 assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE)); 636 verifyInstalledConfig(newConfig); 637 verify(mWifiConfigManager).saveToStore(true); 638 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 639 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 640 641 // Verify data source content. 642 List<PasspointProvider> newProviders = mUserDataSource.getProviders(); 643 assertEquals(1, newProviders.size()); 644 assertEquals(newConfig, newProviders.get(0).getConfig()); 645 assertEquals(2, mSharedDataSource.getProviderIndex()); 646 } 647 648 /** 649 * Verify that adding a provider will fail when failing to install certificates and 650 * key to the keystore. 651 * 652 * @throws Exception 653 */ 654 @Test addProviderOnKeyInstallationFailiure()655 public void addProviderOnKeyInstallationFailiure() throws Exception { 656 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 657 TEST_FRIENDLY_NAME); 658 PasspointProvider provider = mock(PasspointProvider.class); 659 when(provider.installCertsAndKeys()).thenReturn(false); 660 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 661 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 662 provider); 663 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 664 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 665 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 666 } 667 668 /** 669 * Verify that adding a provider with an invalid CA certificate will fail. 670 * 671 * @throws Exception 672 */ 673 @Test addProviderWithInvalidCaCert()674 public void addProviderWithInvalidCaCert() throws Exception { 675 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 676 TEST_FRIENDLY_NAME); 677 doThrow(new GeneralSecurityException()) 678 .when(mCertVerifier).verifyCaCert(any(X509Certificate.class)); 679 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 680 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 681 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 682 } 683 684 /** 685 * Verify that adding a provider with R2 configuration will not perform CA certificate 686 * verification. 687 * 688 * @throws Exception 689 */ 690 @Test addProviderWithR2Config()691 public void addProviderWithR2Config() throws Exception { 692 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 693 TEST_FRIENDLY_NAME); 694 config.setUpdateIdentifier(1); 695 PasspointProvider provider = createMockProvider(config); 696 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 697 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( 698 provider); 699 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 700 verify(mCertVerifier, never()).verifyCaCert(any(X509Certificate.class)); 701 verifyInstalledConfig(config); 702 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 703 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 704 } 705 706 /** 707 * Verify that removing a non-existing provider will fail. 708 * 709 * @throws Exception 710 */ 711 @Test removeNonExistingProvider()712 public void removeNonExistingProvider() throws Exception { 713 assertFalse(mManager.removeProvider(TEST_FQDN)); 714 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 715 verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); 716 } 717 718 /** 719 * Verify that a {code null} will be returned when no providers are installed. 720 * 721 * @throws Exception 722 */ 723 @Test matchProviderWithNoProvidersInstalled()724 public void matchProviderWithNoProvidersInstalled() throws Exception { 725 assertNull(mManager.matchProvider(createTestScanResult())); 726 } 727 728 /** 729 * Verify that a {code null} be returned when ANQP entry doesn't exist in the cache. 730 * 731 * @throws Exception 732 */ 733 @Test matchProviderWithAnqpCacheMissed()734 public void matchProviderWithAnqpCacheMissed() throws Exception { 735 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 736 737 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 738 assertNull(mManager.matchProvider(createTestScanResult())); 739 // Verify that a request for ANQP elements is initiated. 740 verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), any(ANQPNetworkKey.class), 741 anyBoolean(), anyBoolean()); 742 } 743 744 /** 745 * Verify that the expected provider will be returned when a HomeProvider is matched. 746 * 747 * @throws Exception 748 */ 749 @Test matchProviderAsHomeProvider()750 public void matchProviderAsHomeProvider() throws Exception { 751 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 752 ANQPData entry = new ANQPData(mClock, null); 753 754 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 755 when(provider.match(anyMap(), any(RoamingConsortium.class))) 756 .thenReturn(PasspointMatch.HomeProvider); 757 Pair<PasspointProvider, PasspointMatch> result = 758 mManager.matchProvider(createTestScanResult()); 759 assertEquals(PasspointMatch.HomeProvider, result.second); 760 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 761 } 762 763 /** 764 * Verify that the expected provider will be returned when a RoamingProvider is matched. 765 * 766 * @throws Exception 767 */ 768 @Test matchProviderAsRoamingProvider()769 public void matchProviderAsRoamingProvider() throws Exception { 770 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 771 ANQPData entry = new ANQPData(mClock, null); 772 773 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 774 when(provider.match(anyMap(), any(RoamingConsortium.class))) 775 .thenReturn(PasspointMatch.RoamingProvider); 776 Pair<PasspointProvider, PasspointMatch> result = 777 mManager.matchProvider(createTestScanResult()); 778 assertEquals(PasspointMatch.RoamingProvider, result.second); 779 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 780 } 781 782 /** 783 * Verify that a {code null} will be returned when there is no matching provider. 784 * 785 * @throws Exception 786 */ 787 @Test matchProviderWithNoMatch()788 public void matchProviderWithNoMatch() throws Exception { 789 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 790 ANQPData entry = new ANQPData(mClock, null); 791 792 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 793 when(provider.match(anyMap(), any(RoamingConsortium.class))) 794 .thenReturn(PasspointMatch.None); 795 assertNull(mManager.matchProvider(createTestScanResult())); 796 } 797 798 /** 799 * Verify the expectations for sweepCache. 800 * 801 * @throws Exception 802 */ 803 @Test sweepCache()804 public void sweepCache() throws Exception { 805 mManager.sweepCache(); 806 verify(mAnqpCache).sweep(); 807 } 808 809 /** 810 * Verify that an empty map will be returned if ANQP elements are not cached for the given AP. 811 * 812 * @throws Exception 813 */ 814 @Test getANQPElementsWithNoMatchFound()815 public void getANQPElementsWithNoMatchFound() throws Exception { 816 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 817 assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty()); 818 } 819 820 /** 821 * Verify that an expected ANQP elements will be returned if ANQP elements are cached for the 822 * given AP. 823 * 824 * @throws Exception 825 */ 826 @Test getANQPElementsWithMatchFound()827 public void getANQPElementsWithMatchFound() throws Exception { 828 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 829 anqpElementMap.put(ANQPElementType.ANQPDomName, 830 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 831 ANQPData entry = new ANQPData(mClock, anqpElementMap); 832 833 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 834 assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult())); 835 } 836 837 /** 838 * Verify that an expected map of FQDN and a list of ScanResult will be returned when provided 839 * scanResults are matched to installed Passpoint profiles. 840 */ 841 @Test getAllMatchingFqdnsForScanResults()842 public void getAllMatchingFqdnsForScanResults() { 843 // static mocking 844 MockitoSession session = 845 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 846 InformationElementUtil.class).startMocking(); 847 try { 848 PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME, 849 TEST_PACKAGE); 850 WifiConfiguration homeWifiConfiguration = new WifiConfiguration(); 851 homeWifiConfiguration.FQDN = TEST_FQDN + 0; 852 homeWifiConfiguration.isHomeProviderNetwork = true; 853 PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME, 854 TEST_PACKAGE); 855 WifiConfiguration roamingWifiConfiguration = new WifiConfiguration(); 856 roamingWifiConfiguration.FQDN = TEST_FQDN + 1; 857 PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 858 TEST_PACKAGE); 859 ANQPData entry = new ANQPData(mClock, null); 860 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 861 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2; 862 863 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry); 864 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 865 when(providerHome.match(anyMap(), isNull())) 866 .thenReturn(PasspointMatch.HomeProvider); 867 when(providerRoaming.match(anyMap(), isNull())) 868 .thenReturn(PasspointMatch.RoamingProvider); 869 when(providerNone.match(anyMap(), isNull())) 870 .thenReturn(PasspointMatch.None); 871 872 lenient().when(providerHome.getWifiConfig()).thenReturn(homeWifiConfiguration); 873 lenient().when(providerRoaming.getWifiConfig()).thenReturn(roamingWifiConfiguration); 874 lenient().when(providerNone.getWifiConfig()).thenReturn(new WifiConfiguration()); 875 876 Map<String, Map<Integer, List<ScanResult>>> configs = 877 mManager.getAllMatchingFqdnsForScanResults( 878 createTestScanResults()); 879 880 // Expects to be matched with home Provider for each AP (two APs). 881 assertEquals(2, configs.get(TEST_FQDN + 0).get( 882 WifiManager.PASSPOINT_HOME_NETWORK).size()); 883 assertFalse( 884 configs.get(TEST_FQDN + 0).containsKey(WifiManager.PASSPOINT_ROAMING_NETWORK)); 885 886 // Expects to be matched with roaming Provider for each AP (two APs). 887 assertEquals(2, configs.get(TEST_FQDN + 1).get( 888 WifiManager.PASSPOINT_ROAMING_NETWORK).size()); 889 assertFalse(configs.get(TEST_FQDN + 1).containsKey(WifiManager.PASSPOINT_HOME_NETWORK)); 890 891 } finally { 892 session.finishMocking(); 893 } 894 } 895 896 /** 897 * Verify that an expected list of {@link WifiConfiguration} will be returned when provided 898 * a list of FQDN is matched to installed Passpoint profiles. 899 */ 900 @Test getWifiConfigsForPasspointProfiles()901 public void getWifiConfigsForPasspointProfiles() { 902 PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 903 WifiConfiguration wifiConfiguration1 = new WifiConfiguration(); 904 wifiConfiguration1.FQDN = TEST_FQDN; 905 PasspointProvider provider2 = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME, 906 TEST_PACKAGE); 907 WifiConfiguration wifiConfiguration2 = new WifiConfiguration(); 908 wifiConfiguration2.FQDN = TEST_FQDN + 1; 909 PasspointProvider provider3 = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 910 TEST_PACKAGE); 911 WifiConfiguration wifiConfiguration3 = new WifiConfiguration(); 912 wifiConfiguration3.FQDN = TEST_FQDN + 2; 913 lenient().when(provider1.getWifiConfig()).thenReturn(wifiConfiguration1); 914 lenient().when(provider2.getWifiConfig()).thenReturn(wifiConfiguration2); 915 lenient().when(provider3.getWifiConfig()).thenReturn(wifiConfiguration3); 916 917 assertEquals(3, mManager.getWifiConfigsForPasspointProfiles( 918 Arrays.asList(TEST_FQDN, TEST_FQDN + 1, TEST_FQDN + 2)).size()); 919 } 920 921 /** 922 * Verify that an empty map will be returned when trying to get all matching FQDN for a {@code 923 * null} {@link ScanResult}. 924 */ 925 @Test getAllMatchingFqdnsForScanResultsWithNullScanResult()926 public void getAllMatchingFqdnsForScanResultsWithNullScanResult() throws Exception { 927 assertEquals(0, mManager.getAllMatchingFqdnsForScanResults(null).size()); 928 } 929 930 /** 931 * Verify that an empty map will be returned when trying to get a all matching FQDN for a {@link 932 * ScanResult} with a {@code null} BSSID. 933 */ 934 @Test getAllMatchingFqdnsForScanResultsWithNullBSSID()935 public void getAllMatchingFqdnsForScanResultsWithNullBSSID() throws Exception { 936 ScanResult scanResult = createTestScanResult(); 937 scanResult.BSSID = null; 938 939 assertEquals(0, 940 mManager.getAllMatchingFqdnsForScanResults(Arrays.asList(scanResult)).size()); 941 } 942 943 /** 944 * Verify that an empty map will be returned when trying to get all matching FQDN for a {@link 945 * ScanResult} with an invalid BSSID. 946 */ 947 @Test ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID()948 public void ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID() throws Exception { 949 ScanResult scanResult = createTestScanResult(); 950 scanResult.BSSID = "asdfdasfas"; 951 952 assertEquals(0, 953 mManager.getAllMatchingFqdnsForScanResults(Arrays.asList(scanResult)).size()); 954 } 955 956 /** 957 * Verify that an empty map will be returned when trying to get all matching FQDN for a 958 * non-Passpoint AP. 959 */ 960 @Test getAllMatchingFqdnsForScanResultsForNonPasspointAP()961 public void getAllMatchingFqdnsForScanResultsForNonPasspointAP() throws Exception { 962 ScanResult scanResult = createTestScanResult(); 963 scanResult.flags = 0; 964 assertEquals(0, 965 mManager.getAllMatchingFqdnsForScanResults(Arrays.asList(scanResult)).size()); 966 } 967 968 /** 969 * Verify that an empty list will be returned when retrieving OSU providers for an AP with 970 * null scan result. 971 * 972 * @throws Exception 973 */ 974 @Test getMatchingOsuProvidersForNullScanResult()975 public void getMatchingOsuProvidersForNullScanResult() throws Exception { 976 assertTrue(mManager.getMatchingOsuProviders(null).isEmpty()); 977 } 978 979 /** 980 * Verify that an empty list will be returned when retrieving OSU providers for an AP with 981 * invalid BSSID. 982 * 983 * @throws Exception 984 */ 985 @Test getMatchingOsuProvidersForInvalidBSSID()986 public void getMatchingOsuProvidersForInvalidBSSID() throws Exception { 987 ScanResult scanResult = createTestScanResult(); 988 scanResult.BSSID = "asdfdasfas"; 989 assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty()); 990 } 991 992 /** 993 * Verify that an empty list will be returned when retrieving OSU providers for a 994 * non-Passpoint AP. 995 * 996 * @throws Exception 997 */ 998 @Test getMatchingOsuProvidersForNonPasspointAP()999 public void getMatchingOsuProvidersForNonPasspointAP() throws Exception { 1000 ScanResult scanResult = createTestScanResult(); 1001 scanResult.flags = 0; 1002 assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty()); 1003 } 1004 1005 /** 1006 * Verify that an empty list will be returned when no match is found from the ANQP cache. 1007 * 1008 * @throws Exception 1009 */ 1010 @Test getMatchingOsuProviderWithNoMatch()1011 public void getMatchingOsuProviderWithNoMatch() throws Exception { 1012 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 1013 assertTrue( 1014 mManager.getMatchingOsuProviders(Arrays.asList(createTestScanResult())).isEmpty()); 1015 } 1016 1017 /** 1018 * Verify that an expected provider list will be returned when a match is found from 1019 * the ANQP cache with a given list of scanResult. 1020 * 1021 * @throws Exception 1022 */ 1023 @Test getMatchingOsuProvidersWithMatch()1024 public void getMatchingOsuProvidersWithMatch() throws Exception { 1025 // Setup OSU providers ANQP element for AP1. 1026 List<OsuProviderInfo> providerInfoListOfAp1 = new ArrayList<>(); 1027 Map<ANQPElementType, ANQPElement> anqpElementMapOfAp1 = new HashMap<>(); 1028 Set<OsuProvider> expectedOsuProvidersForDomainId = new HashSet<>(); 1029 1030 // Setup OSU providers ANQP element for AP2. 1031 List<OsuProviderInfo> providerInfoListOfAp2 = new ArrayList<>(); 1032 Map<ANQPElementType, ANQPElement> anqpElementMapOfAp2 = new HashMap<>(); 1033 Set<OsuProvider> expectedOsuProvidersForDomainId2 = new HashSet<>(); 1034 int osuProviderCount = 4; 1035 1036 // static mocking 1037 MockitoSession session = 1038 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 1039 InformationElementUtil.class).startMocking(); 1040 try { 1041 for (int i = 0; i < osuProviderCount; i++) { 1042 // Test data. 1043 String friendlyName = "Test Provider" + i; 1044 String serviceDescription = "Dummy Service" + i; 1045 Uri serverUri = Uri.parse("https://" + "test" + i + ".com"); 1046 String nai = "access.test.com"; 1047 List<Integer> methodList = Arrays.asList(1); 1048 List<I18Name> friendlyNames = Arrays.asList( 1049 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, friendlyName)); 1050 List<I18Name> serviceDescriptions = Arrays.asList( 1051 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, 1052 serviceDescription)); 1053 Map<String, String> friendlyNameMap = new HashMap<>(); 1054 friendlyNames.forEach(e -> friendlyNameMap.put(e.getLanguage(), e.getText())); 1055 1056 expectedOsuProvidersForDomainId.add(new OsuProvider( 1057 null, friendlyNameMap, serviceDescription, 1058 serverUri, nai, methodList, null)); 1059 1060 // add All OSU Providers for AP1. 1061 providerInfoListOfAp1.add(new OsuProviderInfo( 1062 friendlyNames, serverUri, methodList, null, nai, serviceDescriptions)); 1063 1064 // add only half of All OSU Providers for AP2. 1065 if (i >= osuProviderCount / 2) { 1066 providerInfoListOfAp2.add(new OsuProviderInfo( 1067 friendlyNames, serverUri, methodList, null, nai, serviceDescriptions)); 1068 expectedOsuProvidersForDomainId2.add(new OsuProvider( 1069 null, friendlyNameMap, serviceDescription, 1070 serverUri, nai, methodList, 1071 null)); 1072 } 1073 } 1074 anqpElementMapOfAp1.put(ANQPElementType.HSOSUProviders, 1075 new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID"), 1076 providerInfoListOfAp1)); 1077 ANQPData anqpData = new ANQPData(mClock, anqpElementMapOfAp1); 1078 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(anqpData); 1079 1080 anqpElementMapOfAp2.put(ANQPElementType.HSOSUProviders, 1081 new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID2"), 1082 providerInfoListOfAp2)); 1083 ANQPData anqpData2 = new ANQPData(mClock, anqpElementMapOfAp2); 1084 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(anqpData2); 1085 1086 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1087 1088 // ANQP_DOMAIN_ID(TEST_ANQP_KEY) 1089 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 1090 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1091 assertEquals(mManager.getMatchingOsuProviders( 1092 Arrays.asList(createTestScanResult())).keySet(), 1093 expectedOsuProvidersForDomainId); 1094 1095 // ANQP_DOMAIN_ID2(TEST_ANQP_KEY2) 1096 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2; 1097 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1098 assertEquals(mManager.getMatchingOsuProviders( 1099 createTestScanResults()).keySet(), expectedOsuProvidersForDomainId2); 1100 } finally { 1101 session.finishMocking(); 1102 } 1103 } 1104 1105 /** 1106 * Verify that matching Passpoint configurations will be returned as map with corresponding 1107 * OSU providers. 1108 */ 1109 @Test getMatchingPasspointConfigsForOsuProvidersWithMatch()1110 public void getMatchingPasspointConfigsForOsuProvidersWithMatch() { 1111 PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1112 PasspointProvider provider2 = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, 1113 TEST_PACKAGE); 1114 1115 List<OsuProvider> osuProviders = new ArrayList<>(); 1116 Map<String, String> friendlyNames = new HashMap<>(); 1117 friendlyNames.put("en", "NO-MATCH-NAME"); 1118 friendlyNames.put("kr", TEST_FRIENDLY_NAME + 1); 1119 1120 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1121 friendlyNames)); 1122 friendlyNames = new HashMap<>(); 1123 friendlyNames.put("en", TEST_FRIENDLY_NAME2); 1124 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1125 friendlyNames)); 1126 1127 Map<OsuProvider, PasspointConfiguration> results = 1128 mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders); 1129 1130 assertEquals(2, results.size()); 1131 assertThat(Arrays.asList(provider1.getConfig(), provider2.getConfig()), 1132 containsInAnyOrder(results.values().toArray())); 1133 } 1134 1135 /** 1136 * Verify that empty map will be returned when there is no matching Passpoint configuration. 1137 */ 1138 @Test getMatchingPasspointConfigsForOsuProvidersWitNoMatch()1139 public void getMatchingPasspointConfigsForOsuProvidersWitNoMatch() { 1140 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1141 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE); 1142 1143 List<OsuProvider> osuProviders = new ArrayList<>(); 1144 1145 Map<String, String> friendlyNames = new HashMap<>(); 1146 friendlyNames.put("en", "NO-MATCH-NAME"); 1147 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1148 friendlyNames)); 1149 friendlyNames = new HashMap<>(); 1150 friendlyNames.put("en", "NO-MATCH-NAME-2"); 1151 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1152 friendlyNames)); 1153 1154 assertEquals(0, mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders).size()); 1155 } 1156 1157 /** 1158 * Verify that the provider list maintained by the PasspointManager after the list is updated 1159 * in the data source. 1160 * 1161 * @throws Exception 1162 */ 1163 @Test verifyProvidersAfterDataSourceUpdate()1164 public void verifyProvidersAfterDataSourceUpdate() throws Exception { 1165 // Update the provider list in the data source. 1166 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 1167 TEST_FRIENDLY_NAME); 1168 PasspointProvider provider = createMockProvider(config); 1169 List<PasspointProvider> providers = new ArrayList<>(); 1170 providers.add(provider); 1171 mUserDataSource.setProviders(providers); 1172 1173 // Verify the providers maintained by PasspointManager. 1174 assertEquals(1, mManager.getProviderConfigs().size()); 1175 assertEquals(config, mManager.getProviderConfigs().get(0)); 1176 } 1177 1178 /** 1179 * Verify that the provider index used by PasspointManager is updated after it is updated in 1180 * the data source. 1181 * 1182 * @throws Exception 1183 */ 1184 @Test verifyProviderIndexAfterDataSourceUpdate()1185 public void verifyProviderIndexAfterDataSourceUpdate() throws Exception { 1186 long providerIndex = 9; 1187 mSharedDataSource.setProviderIndex(providerIndex); 1188 assertEquals(providerIndex, mSharedDataSource.getProviderIndex()); 1189 1190 // Add a provider. 1191 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 1192 TEST_FRIENDLY_NAME); 1193 PasspointProvider provider = createMockProvider(config); 1194 // Verify the provider ID used to create the new provider. 1195 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1196 eq(mSimAccessor), eq(providerIndex), eq(TEST_CREATOR_UID), 1197 eq(TEST_PACKAGE))).thenReturn(provider); 1198 1199 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); 1200 verifyInstalledConfig(config); 1201 verify(mWifiConfigManager).saveToStore(true); 1202 reset(mWifiConfigManager); 1203 } 1204 1205 /** 1206 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1207 * adding a legacy Passpoint configuration containing a valid user credential. 1208 * 1209 * @throws Exception 1210 */ 1211 @Test addLegacyPasspointConfigWithUserCredential()1212 public void addLegacyPasspointConfigWithUserCredential() throws Exception { 1213 // Test data. 1214 String fqdn = "test.com"; 1215 String friendlyName = "Friendly Name"; 1216 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1217 String realm = "realm.com"; 1218 String username = "username"; 1219 String password = "password"; 1220 byte[] base64EncodedPw = 1221 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 1222 String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8); 1223 String caCertificateAlias = "CaCert"; 1224 1225 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1226 WifiConfiguration wifiConfig = new WifiConfiguration(); 1227 wifiConfig.FQDN = fqdn; 1228 wifiConfig.providerFriendlyName = friendlyName; 1229 wifiConfig.roamingConsortiumIds = rcOIs; 1230 wifiConfig.enterpriseConfig.setIdentity(username); 1231 wifiConfig.enterpriseConfig.setPassword(password); 1232 wifiConfig.enterpriseConfig.setRealm(realm); 1233 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); 1234 wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP); 1235 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1236 1237 // Setup expected {@link PasspointConfiguration} 1238 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1239 HomeSp homeSp = new HomeSp(); 1240 homeSp.setFqdn(fqdn); 1241 homeSp.setFriendlyName(friendlyName); 1242 homeSp.setRoamingConsortiumOis(rcOIs); 1243 passpointConfig.setHomeSp(homeSp); 1244 Credential credential = new Credential(); 1245 Credential.UserCredential userCredential = new Credential.UserCredential(); 1246 userCredential.setUsername(username); 1247 userCredential.setPassword(encodedPasswordStr); 1248 userCredential.setEapType(EAPConstants.EAP_TTLS); 1249 userCredential.setNonEapInnerMethod("PAP"); 1250 credential.setUserCredential(userCredential); 1251 credential.setRealm(realm); 1252 passpointConfig.setCredential(credential); 1253 1254 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1255 verifyInstalledConfig(passpointConfig); 1256 } 1257 1258 /** 1259 * Verify that adding a legacy Passpoint configuration containing user credential will 1260 * fail when client certificate is not provided. 1261 * 1262 * @throws Exception 1263 */ 1264 @Test addLegacyPasspointConfigWithUserCredentialWithoutCaCert()1265 public void addLegacyPasspointConfigWithUserCredentialWithoutCaCert() throws Exception { 1266 // Test data. 1267 String fqdn = "test.com"; 1268 String friendlyName = "Friendly Name"; 1269 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1270 String realm = "realm.com"; 1271 String username = "username"; 1272 String password = "password"; 1273 byte[] base64EncodedPw = 1274 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 1275 String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8); 1276 1277 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1278 WifiConfiguration wifiConfig = new WifiConfiguration(); 1279 wifiConfig.FQDN = fqdn; 1280 wifiConfig.providerFriendlyName = friendlyName; 1281 wifiConfig.roamingConsortiumIds = rcOIs; 1282 wifiConfig.enterpriseConfig.setIdentity(username); 1283 wifiConfig.enterpriseConfig.setPassword(password); 1284 wifiConfig.enterpriseConfig.setRealm(realm); 1285 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); 1286 wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP); 1287 1288 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1289 } 1290 1291 /** 1292 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1293 * adding a legacy Passpoint configuration containing a valid SIM credential. 1294 * 1295 * @throws Exception 1296 */ 1297 @Test addLegacyPasspointConfigWithSimCredential()1298 public void addLegacyPasspointConfigWithSimCredential() throws Exception { 1299 // Test data. 1300 String fqdn = "test.com"; 1301 String friendlyName = "Friendly Name"; 1302 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1303 String realm = "realm.com"; 1304 String imsi = "1234"; 1305 1306 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1307 WifiConfiguration wifiConfig = new WifiConfiguration(); 1308 wifiConfig.FQDN = fqdn; 1309 wifiConfig.providerFriendlyName = friendlyName; 1310 wifiConfig.roamingConsortiumIds = rcOIs; 1311 wifiConfig.enterpriseConfig.setRealm(realm); 1312 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 1313 wifiConfig.enterpriseConfig.setPlmn(imsi); 1314 1315 // Setup expected {@link PasspointConfiguration} 1316 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1317 HomeSp homeSp = new HomeSp(); 1318 homeSp.setFqdn(fqdn); 1319 homeSp.setFriendlyName(friendlyName); 1320 homeSp.setRoamingConsortiumOis(rcOIs); 1321 passpointConfig.setHomeSp(homeSp); 1322 Credential credential = new Credential(); 1323 Credential.SimCredential simCredential = new Credential.SimCredential(); 1324 simCredential.setEapType(EAPConstants.EAP_SIM); 1325 simCredential.setImsi(imsi); 1326 credential.setSimCredential(simCredential); 1327 credential.setRealm(realm); 1328 passpointConfig.setCredential(credential); 1329 1330 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1331 verifyInstalledConfig(passpointConfig); 1332 } 1333 1334 /** 1335 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1336 * adding a legacy Passpoint configuration containing a valid certificate credential. 1337 * 1338 * @throws Exception 1339 */ 1340 @Test addLegacyPasspointConfigWithCertCredential()1341 public void addLegacyPasspointConfigWithCertCredential() throws Exception { 1342 // Test data. 1343 String fqdn = "test.com"; 1344 String friendlyName = "Friendly Name"; 1345 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1346 String realm = "realm.com"; 1347 String caCertificateAlias = "CaCert"; 1348 String clientCertificateAlias = "ClientCert"; 1349 1350 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1351 WifiConfiguration wifiConfig = new WifiConfiguration(); 1352 wifiConfig.FQDN = fqdn; 1353 wifiConfig.providerFriendlyName = friendlyName; 1354 wifiConfig.roamingConsortiumIds = rcOIs; 1355 wifiConfig.enterpriseConfig.setRealm(realm); 1356 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1357 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1358 wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias); 1359 1360 // Setup expected {@link PasspointConfiguration} 1361 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1362 HomeSp homeSp = new HomeSp(); 1363 homeSp.setFqdn(fqdn); 1364 homeSp.setFriendlyName(friendlyName); 1365 homeSp.setRoamingConsortiumOis(rcOIs); 1366 passpointConfig.setHomeSp(homeSp); 1367 Credential credential = new Credential(); 1368 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 1369 certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3); 1370 credential.setCertCredential(certCredential); 1371 credential.setRealm(realm); 1372 passpointConfig.setCredential(credential); 1373 1374 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1375 verifyInstalledConfig(passpointConfig); 1376 } 1377 1378 /** 1379 * Verify that adding a legacy Passpoint configuration containing certificate credential will 1380 * fail when CA certificate is not provided. 1381 * 1382 * @throws Exception 1383 */ 1384 @Test addLegacyPasspointConfigWithCertCredentialWithoutCaCert()1385 public void addLegacyPasspointConfigWithCertCredentialWithoutCaCert() throws Exception { 1386 // Test data. 1387 String fqdn = "test.com"; 1388 String friendlyName = "Friendly Name"; 1389 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1390 String realm = "realm.com"; 1391 String clientCertificateAlias = "ClientCert"; 1392 1393 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1394 WifiConfiguration wifiConfig = new WifiConfiguration(); 1395 wifiConfig.FQDN = fqdn; 1396 wifiConfig.providerFriendlyName = friendlyName; 1397 wifiConfig.roamingConsortiumIds = rcOIs; 1398 wifiConfig.enterpriseConfig.setRealm(realm); 1399 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1400 wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias); 1401 1402 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1403 } 1404 1405 /** 1406 * Verify that adding a legacy Passpoint configuration containing certificate credential will 1407 * fail when client certificate is not provided. 1408 * 1409 * @throws Exception 1410 */ 1411 @Test addLegacyPasspointConfigWithCertCredentialWithoutClientCert()1412 public void addLegacyPasspointConfigWithCertCredentialWithoutClientCert() throws Exception { 1413 // Test data. 1414 String fqdn = "test.com"; 1415 String friendlyName = "Friendly Name"; 1416 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1417 String realm = "realm.com"; 1418 String caCertificateAlias = "CaCert"; 1419 1420 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1421 WifiConfiguration wifiConfig = new WifiConfiguration(); 1422 wifiConfig.FQDN = fqdn; 1423 wifiConfig.providerFriendlyName = friendlyName; 1424 wifiConfig.roamingConsortiumIds = rcOIs; 1425 wifiConfig.enterpriseConfig.setRealm(realm); 1426 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1427 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1428 1429 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1430 } 1431 1432 /** 1433 * Verify that the provider's "hasEverConnected" flag will be set to true and the associated 1434 * metric is updated after the provider was used to successfully connect to a Passpoint 1435 * network for the first time. 1436 * 1437 * @throws Exception 1438 */ 1439 @Test providerNetworkConnectedFirstTime()1440 public void providerNetworkConnectedFirstTime() throws Exception { 1441 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1442 when(provider.getHasEverConnected()).thenReturn(false); 1443 mManager.onPasspointNetworkConnected(TEST_FQDN); 1444 verify(provider).setHasEverConnected(eq(true)); 1445 } 1446 1447 /** 1448 * Verify that the provider's "hasEverConnected" flag the associated metric is not updated 1449 * after the provider was used to successfully connect to a Passpoint network for non-first 1450 * time. 1451 * 1452 * @throws Exception 1453 */ 1454 @Test providerNetworkConnectedNotFirstTime()1455 public void providerNetworkConnectedNotFirstTime() throws Exception { 1456 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1457 when(provider.getHasEverConnected()).thenReturn(true); 1458 mManager.onPasspointNetworkConnected(TEST_FQDN); 1459 verify(provider, never()).setHasEverConnected(anyBoolean()); 1460 } 1461 1462 /** 1463 * Verify that the expected Passpoint metrics are updated when 1464 * {@link PasspointManager#updateMetrics} is invoked. 1465 * 1466 * @throws Exception 1467 */ 1468 @Test updateMetrics()1469 public void updateMetrics() { 1470 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1471 ArgumentCaptor<Map<String, PasspointProvider>> argCaptor = ArgumentCaptor.forClass( 1472 Map.class); 1473 // Provider have not provided a successful network connection. 1474 int expectedInstalledProviders = 1; 1475 int expectedConnectedProviders = 0; 1476 when(provider.getHasEverConnected()).thenReturn(false); 1477 mManager.updateMetrics(); 1478 verify(mWifiMetrics).updateSavedPasspointProfiles( 1479 eq(expectedInstalledProviders), eq(expectedConnectedProviders)); 1480 1481 verify(mWifiMetrics).updateSavedPasspointProfilesInfo(argCaptor.capture()); 1482 assertEquals(expectedInstalledProviders, argCaptor.getValue().size()); 1483 assertEquals(provider, argCaptor.getValue().get(TEST_FQDN)); 1484 reset(mWifiMetrics); 1485 1486 // Provider have provided a successful network connection. 1487 expectedConnectedProviders = 1; 1488 when(provider.getHasEverConnected()).thenReturn(true); 1489 mManager.updateMetrics(); 1490 verify(mWifiMetrics).updateSavedPasspointProfiles( 1491 eq(expectedInstalledProviders), eq(expectedConnectedProviders)); 1492 } 1493 1494 /** 1495 * Verify Passpoint Manager's provisioning APIs by invoking methods in PasspointProvisioner for 1496 * initiailization and provisioning a provider. 1497 */ 1498 @Test verifyPasspointProvisioner()1499 public void verifyPasspointProvisioner() { 1500 mManager.initializeProvisioner(mLooper.getLooper()); 1501 verify(mPasspointProvisioner).init(any(Looper.class)); 1502 when(mPasspointProvisioner.startSubscriptionProvisioning(anyInt(), any(OsuProvider.class), 1503 any(IProvisioningCallback.class))).thenReturn(true); 1504 OsuProvider osuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 1505 assertEquals(true, 1506 mManager.startSubscriptionProvisioning(TEST_UID, osuProvider, mCallback)); 1507 } 1508 1509 /** 1510 * Verify that it will return {@code null} if the EAP-Method provided is not a carrier 1511 * EAP-Method. 1512 */ 1513 @Test verifyCreateEphemeralPasspointConfigurationWithNonCarrierEapMethod()1514 public void verifyCreateEphemeralPasspointConfigurationWithNonCarrierEapMethod() { 1515 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 1516 when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); 1517 PasspointManager passpointManager = new PasspointManager(mContext, mWifiInjector, 1518 mHandler, mWifiNative, mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, 1519 mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mTelephonyManager, 1520 mSubscriptionManager); 1521 1522 assertNull(passpointManager.createEphemeralPasspointConfigForCarrier( 1523 EAPConstants.EAP_TLS)); 1524 } 1525 1526 /** 1527 * Verify that it creates an ephemeral Passpoint configuration for the carrier. 1528 */ 1529 @Test verifyCreateEphemeralPasspointConfigurationWithCarrierEapMethod()1530 public void verifyCreateEphemeralPasspointConfigurationWithCarrierEapMethod() { 1531 String mccmnc = "123456"; 1532 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 1533 when(mDataTelephonyManager.getSimOperator()).thenReturn(mccmnc); 1534 when(mDataTelephonyManager.getSimOperatorName()).thenReturn("test"); 1535 PasspointManager passpointManager = new PasspointManager(mContext, mWifiInjector, 1536 mHandler, mWifiNative, mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, 1537 mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mTelephonyManager, 1538 mSubscriptionManager); 1539 1540 PasspointConfiguration result = 1541 passpointManager.createEphemeralPasspointConfigForCarrier( 1542 EAPConstants.EAP_AKA); 1543 1544 assertNotNull(result); 1545 assertTrue(result.validate()); 1546 assertEquals(Utils.getRealmForMccMnc(mccmnc), result.getHomeSp().getFqdn()); 1547 assertEquals(mccmnc + "*", result.getCredential().getSimCredential().getImsi()); 1548 } 1549 1550 /** 1551 * Verify that it will not install the Passpoint configuration with Non-Carrier EAP method. 1552 */ 1553 @Test verifyInstallEphemeralPasspointConfigurationWithNonCarrierEapMethod()1554 public void verifyInstallEphemeralPasspointConfigurationWithNonCarrierEapMethod() { 1555 // SIM is present 1556 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]); 1557 PasspointConfiguration config = createTestConfigWithUserCredential("abc.com", "test"); 1558 PasspointProvider provider = createMockProvider(config); 1559 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1560 eq(mSimAccessor), anyLong(), anyInt(), isNull())).thenReturn(provider); 1561 1562 assertFalse(mManager.installEphemeralPasspointConfigForCarrier(config)); 1563 } 1564 1565 /** 1566 * Verify that it installs the carrier Passpoint configuration successfully. 1567 */ 1568 @Test verifyInstallEphemeralPasspointConfiguration()1569 public void verifyInstallEphemeralPasspointConfiguration() { 1570 // SIM is present 1571 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]); 1572 PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 1573 TEST_REALM); 1574 PasspointProvider provider = createMockProvider(config); 1575 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1576 eq(mSimAccessor), anyLong(), anyInt(), isNull())).thenReturn(provider); 1577 1578 assertTrue(mManager.installEphemeralPasspointConfigForCarrier(config)); 1579 verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), 1580 eq(TEST_PACKAGE), any(AppOpsManager.OnOpChangedListener.class)); 1581 } 1582 1583 /** 1584 * Verify that it returns {@code true} when it has Carrier Provider. 1585 */ 1586 @Test verifyHasProviderForCarrierWithMatch()1587 public void verifyHasProviderForCarrierWithMatch() { 1588 addTestCarrierProvider(TEST_3GPP_FQDN, TEST_MCC_MNC, TEST_3GPP_FQDN); 1589 1590 assertTrue(mManager.hasCarrierProvider(TEST_MCC_MNC)); 1591 } 1592 1593 /** 1594 * Verify that it returns {@code false} when it does not have Carrier Provider. 1595 */ 1596 @Test verifyHasProviderForCarrierWithNoMatch()1597 public void verifyHasProviderForCarrierWithNoMatch() { 1598 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1599 1600 assertFalse(mManager.hasCarrierProvider(TEST_MCC_MNC)); 1601 } 1602 1603 /** 1604 * Verify that it returns a carrier EAP-method from NAI-Realm matched with the carrier. 1605 */ 1606 @Test verifyFindEapMethodFromNAIRealmMatchedWithCarrierWithMatch()1607 public void verifyFindEapMethodFromNAIRealmMatchedWithCarrierWithMatch() { 1608 // static mocking 1609 MockitoSession session = ExtendedMockito.mockitoSession() 1610 .mockStatic(InformationElementUtil.class) 1611 .startMocking(); 1612 try { 1613 when(mTelephonyManager.createForSubscriptionId(anyInt())) 1614 .thenReturn(mDataTelephonyManager); 1615 when(mDataTelephonyManager.getSimOperator()).thenReturn(TEST_MCC_MNC); 1616 // SIM is present 1617 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]); 1618 List<ScanDetail> scanDetails = new ArrayList<>(); 1619 scanDetails.add(generateScanDetail(TEST_SSID, TEST_BSSID_STRING, TEST_HESSID, 1620 TEST_ANQP_DOMAIN_ID, true)); 1621 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1622 1623 // ANQP_DOMAIN_ID(TEST_ANQP_KEY) 1624 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 1625 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1626 Map<ANQPElementType, ANQPElement> anqpElementMapOfAp1 = new HashMap<>(); 1627 List<NAIRealmData> realmDataList = new ArrayList<>(); 1628 realmDataList.add(new NAIRealmData(Arrays.asList(TEST_3GPP_FQDN), 1629 Arrays.asList(new EAPMethod(EAPConstants.EAP_AKA, null)))); 1630 anqpElementMapOfAp1.put(ANQPElementType.ANQPNAIRealm, 1631 new NAIRealmElement(realmDataList)); 1632 1633 ANQPData anqpData = new ANQPData(mClock, anqpElementMapOfAp1); 1634 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(anqpData); 1635 1636 PasspointManager passpointManager = new PasspointManager(mContext, mWifiInjector, 1637 mHandler, mWifiNative, mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, 1638 mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mTelephonyManager, 1639 mSubscriptionManager); 1640 assertEquals(EAPConstants.EAP_AKA, 1641 passpointManager.findEapMethodFromNAIRealmMatchedWithCarrier(scanDetails)); 1642 } finally { 1643 session.finishMocking(); 1644 } 1645 } 1646 1647 /** 1648 * Verify that it returns -1 when there is no NAI-Realm matched with the carrier. 1649 */ 1650 @Test verifyFindEapMethodFromNAIRealmMatchedWithCarrierWithNoMatch()1651 public void verifyFindEapMethodFromNAIRealmMatchedWithCarrierWithNoMatch() { 1652 // static mocking 1653 MockitoSession session = ExtendedMockito.mockitoSession() 1654 .mockStatic(InformationElementUtil.class) 1655 .startMocking(); 1656 try { 1657 when(mTelephonyManager.createForSubscriptionId(anyInt())) 1658 .thenReturn(mDataTelephonyManager); 1659 when(mDataTelephonyManager.getSimOperator()).thenReturn(TEST_MCC_MNC); 1660 // SIM is present 1661 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]); 1662 List<ScanDetail> scanDetails = new ArrayList<>(); 1663 scanDetails.add(generateScanDetail(TEST_SSID, TEST_BSSID_STRING, 0, 0, false)); 1664 1665 PasspointManager passpointManager = new PasspointManager(mContext, mWifiInjector, 1666 mHandler, mWifiNative, mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, 1667 mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mTelephonyManager, 1668 mSubscriptionManager); 1669 1670 assertEquals(-1, 1671 passpointManager.findEapMethodFromNAIRealmMatchedWithCarrier(scanDetails)); 1672 } finally { 1673 session.finishMocking(); 1674 } 1675 } 1676 1677 /** 1678 * Verify that the corresponding Passpoint provider is removed when the app is disabled. 1679 */ 1680 @Test verifyRemovingPasspointProfilesWhenAppIsDisabled()1681 public void verifyRemovingPasspointProfilesWhenAppIsDisabled() { 1682 WifiConfiguration currentConfiguration = WifiConfigurationTestUtil.createPasspointNetwork(); 1683 currentConfiguration.FQDN = TEST_FQDN; 1684 when(mClientModeImpl.getCurrentWifiConfiguration()).thenReturn(currentConfiguration); 1685 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE); 1686 1687 verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), 1688 mAppOpChangedListenerCaptor.capture()); 1689 assertEquals(1, mManager.getProviderConfigs().size()); 1690 AppOpsManager.OnOpChangedListener listener = mAppOpChangedListenerCaptor.getValue(); 1691 assertNotNull(listener); 1692 1693 // Disallow change wifi state & ensure we remove the profiles from database. 1694 when(mAppOpsManager.unsafeCheckOpNoThrow( 1695 OPSTR_CHANGE_WIFI_STATE, TEST_CREATOR_UID, 1696 TEST_PACKAGE)) 1697 .thenReturn(MODE_IGNORED); 1698 listener.onOpChanged(OPSTR_CHANGE_WIFI_STATE, TEST_PACKAGE); 1699 mLooper.dispatchAll(); 1700 1701 verify(mAppOpsManager).stopWatchingMode(mAppOpChangedListenerCaptor.getValue()); 1702 verify(mClientModeImpl).disconnectCommand(); 1703 assertTrue(mManager.getProviderConfigs().isEmpty()); 1704 } 1705 } 1706