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