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.WifiConfiguration.METERED_OVERRIDE_METERED; 22 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED; 23 import static android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS; 24 25 import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_EAP; 26 27 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; 28 import static org.junit.Assert.assertEquals; 29 import static org.junit.Assert.assertFalse; 30 import static org.junit.Assert.assertNotNull; 31 import static org.junit.Assert.assertNull; 32 import static org.junit.Assert.assertThat; 33 import static org.junit.Assert.assertTrue; 34 import static org.mockito.ArgumentMatchers.argThat; 35 import static org.mockito.ArgumentMatchers.isNull; 36 import static org.mockito.Mockito.any; 37 import static org.mockito.Mockito.anyBoolean; 38 import static org.mockito.Mockito.anyInt; 39 import static org.mockito.Mockito.anyLong; 40 import static org.mockito.Mockito.anyMap; 41 import static org.mockito.Mockito.atLeastOnce; 42 import static org.mockito.Mockito.doAnswer; 43 import static org.mockito.Mockito.eq; 44 import static org.mockito.Mockito.lenient; 45 import static org.mockito.Mockito.mock; 46 import static org.mockito.Mockito.never; 47 import static org.mockito.Mockito.reset; 48 import static org.mockito.Mockito.spy; 49 import static org.mockito.Mockito.times; 50 import static org.mockito.Mockito.verify; 51 import static org.mockito.Mockito.when; 52 import static org.mockito.MockitoAnnotations.initMocks; 53 54 import android.app.ActivityManager; 55 import android.app.AppOpsManager; 56 import android.content.Context; 57 import android.content.Intent; 58 import android.net.MacAddress; 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.WifiContext; 64 import android.net.wifi.WifiEnterpriseConfig; 65 import android.net.wifi.WifiManager; 66 import android.net.wifi.WifiSsid; 67 import android.net.wifi.hotspot2.IProvisioningCallback; 68 import android.net.wifi.hotspot2.OsuProvider; 69 import android.net.wifi.hotspot2.PasspointConfiguration; 70 import android.net.wifi.hotspot2.pps.Credential; 71 import android.net.wifi.hotspot2.pps.HomeSp; 72 import android.os.Handler; 73 import android.os.Looper; 74 import android.os.UserHandle; 75 import android.os.test.TestLooper; 76 import android.telephony.SubscriptionInfo; 77 import android.telephony.SubscriptionManager; 78 import android.telephony.TelephonyManager; 79 import android.util.Base64; 80 import android.util.Pair; 81 82 import androidx.test.filters.SmallTest; 83 84 import com.android.server.wifi.Clock; 85 import com.android.server.wifi.FakeKeys; 86 import com.android.server.wifi.FrameworkFacade; 87 import com.android.server.wifi.MacAddressUtil; 88 import com.android.server.wifi.NetworkUpdateResult; 89 import com.android.server.wifi.WifiBaseTest; 90 import com.android.server.wifi.WifiCarrierInfoManager; 91 import com.android.server.wifi.WifiConfigManager; 92 import com.android.server.wifi.WifiConfigStore; 93 import com.android.server.wifi.WifiConfigurationTestUtil; 94 import com.android.server.wifi.WifiInjector; 95 import com.android.server.wifi.WifiKeyStore; 96 import com.android.server.wifi.WifiMetrics; 97 import com.android.server.wifi.WifiNative; 98 import com.android.server.wifi.WifiNetworkSuggestionsManager; 99 import com.android.server.wifi.WifiSettingsStore; 100 import com.android.server.wifi.hotspot2.anqp.ANQPElement; 101 import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; 102 import com.android.server.wifi.hotspot2.anqp.DomainNameElement; 103 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement; 104 import com.android.server.wifi.hotspot2.anqp.I18Name; 105 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo; 106 import com.android.server.wifi.hotspot2.anqp.VenueNameElement; 107 import com.android.server.wifi.hotspot2.anqp.VenueUrlElement; 108 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent; 109 import com.android.server.wifi.util.InformationElementUtil; 110 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium; 111 import com.android.server.wifi.util.WifiPermissionsUtil; 112 113 import org.junit.Before; 114 import org.junit.BeforeClass; 115 import org.junit.Test; 116 import org.mockito.ArgumentCaptor; 117 import org.mockito.Mock; 118 import org.mockito.MockitoSession; 119 120 import java.net.URL; 121 import java.nio.charset.StandardCharsets; 122 import java.security.KeyStore; 123 import java.security.cert.Certificate; 124 import java.security.cert.PKIXParameters; 125 import java.security.cert.X509Certificate; 126 import java.util.ArrayList; 127 import java.util.Arrays; 128 import java.util.Collections; 129 import java.util.HashMap; 130 import java.util.HashSet; 131 import java.util.List; 132 import java.util.Locale; 133 import java.util.Map; 134 import java.util.Set; 135 import java.util.stream.Collectors; 136 137 /** 138 * Unit tests for {@link PasspointManager}. 139 */ 140 @SmallTest 141 public class PasspointManagerTest extends WifiBaseTest { 142 private static final long BSSID = 0x112233445566L; 143 private static final String TEST_PACKAGE = "com.android.test"; 144 private static final String TEST_PACKAGE1 = "com.android.test1"; 145 private static final String TEST_FQDN = "test1.test.com"; 146 private static final String TEST_FQDN2 = "test2.test.com"; 147 private static final String TEST_FRIENDLY_NAME = "friendly name"; 148 private static final String TEST_FRIENDLY_NAME2 = "second friendly name"; 149 private static final String TEST_REALM = "realm.test.com"; 150 private static final String TEST_REALM2 = "realm.test2.com"; 151 private static final String TEST_REALM3 = "realm.test3.com"; 152 private static final String TEST_IMSI = "123456*"; 153 private static final String FULL_IMSI = "123456789123456"; 154 private static final int TEST_CARRIER_ID = 10; 155 private static final int TEST_SUBID = 1; 156 private static final String TEST_VENUE_URL_ENG = "https://www.google.com/"; 157 private static final String TEST_VENUE_URL_HEB = "https://www.google.co.il/"; 158 private static final String TEST_LOCALE_ENGLISH = "eng"; 159 private static final String TEST_LOCALE_HEBREW = "heb"; 160 private static final String TEST_LOCALE_SPANISH = "spa"; 161 private static final String TEST_TERMS_AND_CONDITIONS_URL = 162 "https://policies.google.com/terms?hl=en-US"; 163 private static final String TEST_TERMS_AND_CONDITIONS_URL_NON_HTTPS = 164 "http://policies.google.com/terms?hl=en-US"; 165 private static final String TEST_TERMS_AND_CONDITIONS_URL_INVALID = 166 "httpps://policies.google.com/terms?hl=en-US"; 167 168 private static final long TEST_BSSID = 0x112233445566L; 169 private static final String TEST_SSID = "TestSSID"; 170 private static final String TEST_BSSID_STRING = "11:22:33:44:55:66"; 171 private static final String TEST_SSID2 = "TestSSID2"; 172 private static final String TEST_BSSID_STRING2 = "11:22:33:44:55:77"; 173 private static final String TEST_SSID3 = "TestSSID3"; 174 private static final String TEST_BSSID_STRING3 = "11:22:33:44:55:88"; 175 private static final String TEST_MCC_MNC = "123456"; 176 private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org", 177 TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3)); 178 179 private static final long TEST_HESSID = 0x5678L; 180 private static final int TEST_ANQP_DOMAIN_ID = 0; 181 private static final int TEST_ANQP_DOMAIN_ID2 = 1; 182 private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey( 183 TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID); 184 private static final ANQPNetworkKey TEST_ANQP_KEY2 = ANQPNetworkKey.buildKey( 185 TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID2); 186 private static final int TEST_CREATOR_UID = 1234; 187 private static final int TEST_CREATOR_UID1 = 1235; 188 private static final int TEST_UID = 1500; 189 private static final int TEST_NETWORK_ID = 2; 190 private static final String TEST_ANONYMOUS_IDENTITY = "AnonymousIdentity"; 191 private static final String USER_CONNECT_CHOICE = "SomeNetworkProfileId"; 192 private static final int TEST_RSSI = -50; 193 public static PKIXParameters TEST_PKIX_PARAMETERS; 194 195 @Mock Context mContext; 196 @Mock WifiNative mWifiNative; 197 @Mock WifiKeyStore mWifiKeyStore; 198 @Mock Clock mClock; 199 @Mock PasspointObjectFactory mObjectFactory; 200 @Mock PasspointEventHandler.Callbacks mCallbacks; 201 @Mock AnqpCache mAnqpCache; 202 @Mock ANQPRequestManager mAnqpRequestManager; 203 @Mock WifiConfigManager mWifiConfigManager; 204 @Mock WifiConfigStore mWifiConfigStore; 205 @Mock WifiSettingsStore mWifiSettingsStore; 206 PasspointConfigSharedStoreData.DataSource mSharedDataSource; 207 PasspointConfigUserStoreData.DataSource mUserDataSource; 208 @Mock WifiMetrics mWifiMetrics; 209 @Mock OsuNetworkConnection mOsuNetworkConnection; 210 @Mock OsuServerConnection mOsuServerConnection; 211 @Mock PasspointProvisioner mPasspointProvisioner; 212 @Mock PasspointNetworkNominateHelper mPasspointNetworkNominateHelper; 213 @Mock IProvisioningCallback mCallback; 214 @Mock WfaKeyStore mWfaKeyStore; 215 @Mock KeyStore mKeyStore; 216 @Mock AppOpsManager mAppOpsManager; 217 @Mock WifiInjector mWifiInjector; 218 @Mock TelephonyManager mTelephonyManager; 219 @Mock SubscriptionManager mSubscriptionManager; 220 @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; 221 @Mock MacAddressUtil mMacAddressUtil; 222 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 223 @Mock ActivityManager mActivityManager; 224 225 Handler mHandler; 226 TestLooper mLooper; 227 PasspointManager mManager; 228 boolean mConfigSettingsPasspointEnabled = true; 229 ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor = 230 ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class); 231 WifiCarrierInfoManager mWifiCarrierInfoManager; 232 ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mNetworkListenerCaptor = 233 ArgumentCaptor.forClass(WifiConfigManager.OnNetworkUpdateListener.class); 234 ArgumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener> mSubscriptionsCaptor = 235 ArgumentCaptor.forClass(SubscriptionManager.OnSubscriptionsChangedListener.class); 236 237 @BeforeClass setUpBeforeClass()238 public static void setUpBeforeClass() throws Exception { 239 KeyStore keyStore = KeyStore.getInstance("AndroidCAStore"); 240 keyStore.load(null, null); 241 TEST_PKIX_PARAMETERS = new PKIXParameters(keyStore); 242 TEST_PKIX_PARAMETERS.setRevocationEnabled(false); 243 } 244 245 /** Sets up test. */ 246 @Before setUp()247 public void setUp() throws Exception { 248 initMocks(this); 249 when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache); 250 when(mObjectFactory.makeANQPRequestManager(any(), eq(mClock))) 251 .thenReturn(mAnqpRequestManager); 252 when(mObjectFactory.makeOsuNetworkConnection(any(Context.class))) 253 .thenReturn(mOsuNetworkConnection); 254 when(mObjectFactory.makeOsuServerConnection()) 255 .thenReturn(mOsuServerConnection); 256 when(mObjectFactory.makeWfaKeyStore()).thenReturn(mWfaKeyStore); 257 when(mWfaKeyStore.get()).thenReturn(mKeyStore); 258 when(mObjectFactory.makePasspointProvisioner(any(Context.class), any(WifiNative.class), 259 any(PasspointManager.class), any(WifiMetrics.class))) 260 .thenReturn(mPasspointProvisioner); 261 when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); 262 when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager); 263 when(mWifiInjector.getWifiNetworkSuggestionsManager()) 264 .thenReturn(mWifiNetworkSuggestionsManager); 265 when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt())) 266 .thenReturn(true); 267 // Update mConfigSettingsPasspointEnabled when WifiSettingsStore#handleWifiPasspointEnabled 268 // is called. 269 doAnswer(invocation -> { 270 mConfigSettingsPasspointEnabled = (boolean) invocation.getArguments()[0]; 271 // Return success 272 return true; 273 }).when(mWifiSettingsStore).handleWifiPasspointEnabled(anyBoolean()); 274 when(mWifiSettingsStore.isWifiPasspointEnabled()) 275 .thenReturn(mConfigSettingsPasspointEnabled); 276 mLooper = new TestLooper(); 277 mHandler = new Handler(mLooper.getLooper()); 278 mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager, 279 mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class), 280 mock(WifiContext.class), mWifiConfigStore, mHandler, mWifiMetrics, mClock); 281 verify(mSubscriptionManager).addOnSubscriptionsChangedListener(any(), 282 mSubscriptionsCaptor.capture()); 283 mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative, 284 mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager, 285 mWifiConfigStore, mWifiSettingsStore, mWifiMetrics, mWifiCarrierInfoManager, 286 mMacAddressUtil, mWifiPermissionsUtil); 287 mManager.setPasspointNetworkNominateHelper(mPasspointNetworkNominateHelper); 288 // Verify Passpoint is enabled on creation. 289 assertTrue(mManager.isWifiPasspointEnabled()); 290 mManager.setUseInjectedPKIX(true); 291 mManager.injectPKIXParameters(TEST_PKIX_PARAMETERS); 292 293 ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks = 294 ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class); 295 verify(mObjectFactory).makePasspointEventHandler(any(WifiInjector.class), 296 callbacks.capture()); 297 ArgumentCaptor<PasspointConfigSharedStoreData.DataSource> sharedDataSource = 298 ArgumentCaptor.forClass(PasspointConfigSharedStoreData.DataSource.class); 299 verify(mObjectFactory).makePasspointConfigSharedStoreData(sharedDataSource.capture()); 300 ArgumentCaptor<PasspointConfigUserStoreData.DataSource> userDataSource = 301 ArgumentCaptor.forClass(PasspointConfigUserStoreData.DataSource.class); 302 verify(mObjectFactory).makePasspointConfigUserStoreData(any(WifiKeyStore.class), 303 any(WifiCarrierInfoManager.class), userDataSource.capture(), any(Clock.class)); 304 mCallbacks = callbacks.getValue(); 305 mSharedDataSource = sharedDataSource.getValue(); 306 mUserDataSource = userDataSource.getValue(); 307 // SIM is absent 308 when(mSubscriptionManager.getActiveSubscriptionInfoList()) 309 .thenReturn(Collections.emptyList()); 310 mLooper.dispatchAll(); 311 verify(mWifiConfigManager).addOnNetworkUpdateListener(mNetworkListenerCaptor.capture()); 312 } 313 314 /** 315 * Verify that the given Passpoint configuration matches the one that's added to 316 * the PasspointManager. 317 * 318 * @param expectedConfig The expected installed Passpoint configuration 319 */ verifyInstalledConfig(PasspointConfiguration expectedConfig)320 private void verifyInstalledConfig(PasspointConfiguration expectedConfig) { 321 List<PasspointConfiguration> installedConfigs = 322 mManager.getProviderConfigs(TEST_CREATOR_UID, true); 323 assertEquals(1, installedConfigs.size()); 324 assertEquals(expectedConfig, installedConfigs.get(0)); 325 } 326 createMockProvider(PasspointConfiguration config)327 private PasspointProvider createMockProvider(PasspointConfiguration config) { 328 WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1, 329 TEST_UID, "\"PasspointTestSSID\"", true, true, 330 config.getHomeSp().getFqdn(), TEST_FRIENDLY_NAME, SECURITY_EAP); 331 return createMockProvider(config, wifiConfig, false); 332 } 333 334 /** 335 * Create a mock PasspointProvider with default expectations. 336 * 337 * @param config The configuration associated with the provider 338 * @return {@link com.android.server.wifi.hotspot2.PasspointProvider} 339 */ createMockProvider( PasspointConfiguration config, WifiConfiguration wifiConfig, boolean isSuggestion)340 private PasspointProvider createMockProvider( 341 PasspointConfiguration config, WifiConfiguration wifiConfig, boolean isSuggestion) { 342 PasspointProvider provider = mock(PasspointProvider.class); 343 when(provider.installCertsAndKeys()).thenReturn(true); 344 lenient().when(provider.getConfig()).thenReturn(config); 345 lenient().when(provider.getWifiConfig()).thenReturn(wifiConfig); 346 lenient().when(provider.getCreatorUid()).thenReturn(TEST_CREATOR_UID); 347 lenient().when(provider.isFromSuggestion()).thenReturn(isSuggestion); 348 lenient().when(provider.isAutojoinEnabled()).thenReturn(true); 349 return provider; 350 } 351 352 /** 353 * Helper function for creating a test configuration with user credential. 354 * 355 * @return {@link PasspointConfiguration} 356 */ createTestConfigWithUserCredential(String fqdn, String friendlyName)357 private PasspointConfiguration createTestConfigWithUserCredential(String fqdn, 358 String friendlyName) { 359 return createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, TEST_REALM); 360 } 361 362 /** 363 * Helper function for creating a test configuration with user credential 364 * and a unique realm. 365 * 366 * @return {@link PasspointConfiguration} 367 */ createTestConfigWithUserCredentialAndRealm(String fqdn, String friendlyName, String realm)368 private PasspointConfiguration createTestConfigWithUserCredentialAndRealm(String fqdn, 369 String friendlyName, String realm) { 370 PasspointConfiguration config = new PasspointConfiguration(); 371 HomeSp homeSp = new HomeSp(); 372 homeSp.setFqdn(fqdn); 373 homeSp.setFriendlyName(friendlyName); 374 config.setHomeSp(homeSp); 375 Credential credential = new Credential(); 376 credential.setRealm(realm != null ? realm : TEST_REALM); 377 credential.setCaCertificate(FakeKeys.CA_CERT0); 378 Credential.UserCredential userCredential = new Credential.UserCredential(); 379 userCredential.setUsername("username"); 380 userCredential.setPassword("password"); 381 userCredential.setEapType(EAPConstants.EAP_TTLS); 382 userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAP); 383 credential.setUserCredential(userCredential); 384 config.setCredential(credential); 385 return config; 386 } 387 388 /** 389 * Helper function for creating a test configuration with SIM credential. 390 * 391 * @return {@link PasspointConfiguration} 392 */ createTestConfigWithSimCredential(String fqdn, String imsi, String realm)393 private PasspointConfiguration createTestConfigWithSimCredential(String fqdn, String imsi, 394 String realm) { 395 PasspointConfiguration config = new PasspointConfiguration(); 396 HomeSp homeSp = new HomeSp(); 397 homeSp.setFqdn(fqdn); 398 homeSp.setFriendlyName(TEST_FRIENDLY_NAME); 399 config.setHomeSp(homeSp); 400 Credential credential = new Credential(); 401 credential.setRealm(TEST_REALM); 402 Credential.SimCredential simCredential = new Credential.SimCredential(); 403 simCredential.setImsi(imsi); 404 simCredential.setEapType(EAPConstants.EAP_SIM); 405 credential.setSimCredential(simCredential); 406 config.setCredential(credential); 407 return config; 408 } 409 addTestProvider(String fqdn, String friendlyName, String packageName, boolean isSuggestion, String realm, boolean addServiceFriendlyNames)410 private PasspointProvider addTestProvider(String fqdn, String friendlyName, 411 String packageName, boolean isSuggestion, String realm, 412 boolean addServiceFriendlyNames) { 413 WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1, TEST_UID, 414 "\"PasspointTestSSID\"", true, true, 415 fqdn, friendlyName, SECURITY_EAP); 416 417 return addTestProvider(fqdn, friendlyName, packageName, wifiConfig, isSuggestion, realm, 418 addServiceFriendlyNames); 419 } 420 421 /** 422 * Helper function for adding a test provider to the manager. Return the mock 423 * provider that's added to the manager. 424 * 425 * @return {@link PasspointProvider} 426 */ addTestProvider(String fqdn, String friendlyName, String packageName, WifiConfiguration wifiConfig, boolean isSuggestion, String realm, boolean addServiceFriendlyNames)427 private PasspointProvider addTestProvider(String fqdn, String friendlyName, 428 String packageName, WifiConfiguration wifiConfig, boolean isSuggestion, String realm, 429 boolean addServiceFriendlyNames) { 430 PasspointConfiguration config = 431 createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, realm); 432 wifiConfig.setPasspointUniqueId(config.getUniqueId()); 433 if (addServiceFriendlyNames) { 434 Map<String, String> friendlyNames = new HashMap<>(); 435 friendlyNames.put("en", friendlyName); 436 friendlyNames.put("kr", friendlyName + 1); 437 friendlyNames.put("jp", friendlyName + 2); 438 config.setServiceFriendlyNames(friendlyNames); 439 } 440 PasspointProvider provider = createMockProvider(config, wifiConfig, isSuggestion); 441 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 442 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 443 eq(isSuggestion), eq(mClock))).thenReturn(provider); 444 when(provider.getPackageName()).thenReturn(packageName); 445 assertTrue(mManager.addOrUpdateProvider( 446 config, TEST_CREATOR_UID, TEST_PACKAGE, isSuggestion, true)); 447 verify(mPasspointNetworkNominateHelper, atLeastOnce()) 448 .updateBestMatchScanDetailForProviders(); 449 return provider; 450 } 451 452 /** 453 * Helper function for creating a ScanResult for testing. 454 * 455 * @return {@link ScanResult} 456 */ createTestScanResult()457 private ScanResult createTestScanResult() { 458 ScanResult scanResult = new ScanResult(); 459 scanResult.SSID = TEST_SSID; 460 scanResult.BSSID = TEST_BSSID_STRING; 461 scanResult.hessid = TEST_HESSID; 462 scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID; 463 scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 464 return scanResult; 465 } 466 467 /** 468 * Helper function for creating a ScanResult for testing. 469 * 470 * @return {@link ScanResult} 471 */ createTestScanResults()472 private List<ScanResult> createTestScanResults() { 473 List<ScanResult> scanResults = new ArrayList<>(); 474 475 // Passpoint AP 476 ScanResult scanResult = new ScanResult(); 477 scanResult.SSID = TEST_SSID; 478 scanResult.BSSID = TEST_BSSID_STRING; 479 scanResult.hessid = TEST_HESSID; 480 scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 481 scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID2; 482 scanResults.add(scanResult); 483 484 // Non-Passpoint AP 485 ScanResult scanResult2 = new ScanResult(); 486 scanResult2.SSID = TEST_SSID2; 487 scanResult2.BSSID = TEST_BSSID_STRING2; 488 scanResult2.hessid = TEST_HESSID; 489 scanResult2.flags = 0; 490 scanResults.add(scanResult2); 491 492 // Passpoint AP 493 ScanResult scanResult3 = new ScanResult(); 494 scanResult3.SSID = TEST_SSID3; 495 scanResult3.BSSID = TEST_BSSID_STRING3; 496 scanResult3.hessid = TEST_HESSID; 497 scanResult3.flags = ScanResult.FLAG_PASSPOINT_NETWORK; 498 scanResult3.anqpDomainId = TEST_ANQP_DOMAIN_ID2; 499 scanResults.add(scanResult3); 500 501 return scanResults; 502 } 503 504 /** 505 * Verify that the ANQP elements will be added to the ANQP cache on receiving a successful 506 * response. 507 * 508 * @throws Exception 509 */ 510 @Test anqpResponseSuccess()511 public void anqpResponseSuccess() throws Exception { 512 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 513 anqpElementMap.put(ANQPElementType.ANQPDomName, 514 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 515 516 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY); 517 mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); 518 verify(mAnqpCache).addOrUpdateEntry(TEST_ANQP_KEY, anqpElementMap); 519 verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), 520 any(String.class)); 521 } 522 523 /** 524 * Verify that no ANQP elements will be added to the ANQP cache on receiving a successful 525 * response for a request that's not sent by us. 526 * 527 * @throws Exception 528 */ 529 @Test anqpResponseSuccessWithUnknownRequest()530 public void anqpResponseSuccessWithUnknownRequest() throws Exception { 531 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 532 anqpElementMap.put(ANQPElementType.ANQPDomName, 533 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 534 535 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null); 536 mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); 537 verify(mAnqpCache, never()).addOrUpdateEntry(any(ANQPNetworkKey.class), anyMap()); 538 } 539 540 /** 541 * Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response. 542 * 543 * @throws Exception 544 */ 545 @Test anqpResponseFailure()546 public void anqpResponseFailure() throws Exception { 547 when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY); 548 mCallbacks.onANQPResponse(TEST_BSSID, null); 549 verify(mAnqpCache, never()).addOrUpdateEntry(any(ANQPNetworkKey.class), anyMap()); 550 551 } 552 553 /** 554 * Verify that adding a provider with a null configuration will fail. 555 * 556 * @throws Exception 557 */ 558 @Test addProviderWithNullConfig()559 public void addProviderWithNullConfig() throws Exception { 560 assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE, 561 false, true)); 562 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 563 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 564 } 565 566 /** 567 * Verify that adding a provider with a empty configuration will fail. 568 * 569 * @throws Exception 570 */ 571 @Test addProviderWithEmptyConfig()572 public void addProviderWithEmptyConfig() throws Exception { 573 assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID, 574 TEST_PACKAGE, false, true)); 575 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 576 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 577 } 578 579 /** 580 * Verify taht adding a provider with an invalid credential will fail (using EAP-TLS 581 * for user credential). 582 * 583 * @throws Exception 584 */ 585 @Test addProviderWithInvalidCredential()586 public void addProviderWithInvalidCredential() throws Exception { 587 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 588 TEST_FRIENDLY_NAME); 589 // EAP-TLS not allowed for user credential. 590 config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS); 591 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 592 false, true)); 593 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 594 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 595 } 596 597 /** 598 * Verify that adding a provider from a background user will fail. 599 * 600 * @throws Exception 601 */ 602 @Test addProviderWithBackgroundUser()603 public void addProviderWithBackgroundUser() throws Exception { 604 when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt())) 605 .thenReturn(false); 606 607 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 608 TEST_FRIENDLY_NAME); 609 PasspointProvider provider = createMockProvider(config); 610 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 611 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 612 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 613 eq(false), eq(mClock))).thenReturn(provider); 614 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, 615 TEST_PACKAGE, false, true)); 616 617 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 618 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 619 } 620 621 /** 622 * Verify that adding a user saved provider with a valid configuration and user credential will 623 * succeed. 624 * 625 * @throws Exception 626 */ addRemoveSavedProviderWithValidUserCredential(boolean useFqdn)627 private void addRemoveSavedProviderWithValidUserCredential(boolean useFqdn) throws Exception { 628 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 629 TEST_FRIENDLY_NAME); 630 PasspointProvider provider = createMockProvider(config); 631 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 632 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 633 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 634 eq(false), eq(mClock))).thenReturn(provider); 635 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 636 false, true)); 637 verifyInstalledConfig(config); 638 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 639 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 640 verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), 641 any(AppOpsManager.OnOpChangedListener.class)); 642 reset(mWifiMetrics); 643 reset(mWifiConfigManager); 644 645 // Verify content in the data source. 646 List<PasspointProvider> providers = mUserDataSource.getProviders(); 647 assertEquals(1, providers.size()); 648 assertEquals(config, providers.get(0).getConfig()); 649 650 // Verify calling |enableAutoJoin|, |enableMacRandomization|, and |setMeteredOverride| 651 verifyEnableAutojoin(providers.get(0), useFqdn); 652 verifyEnableMacRandomization(providers.get(0)); 653 verifySetMeteredOverride(providers.get(0)); 654 655 // Provider index start with 0, should be 1 after adding a provider. 656 assertEquals(1, mSharedDataSource.getProviderIndex()); 657 658 // Remove the provider as the creator app. 659 if (useFqdn) { 660 assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN)); 661 } else { 662 assertTrue( 663 mManager.removeProvider(TEST_CREATOR_UID, false, config.getUniqueId(), null)); 664 } 665 666 verify(provider).uninstallCertsAndKeys(); 667 verify(mWifiConfigManager, times(3)).removePasspointConfiguredNetwork( 668 provider.getWifiConfig().getProfileKey()); 669 /** 670 * 1 from |removeProvider| + 2 from |setAutojoinEnabled| + 2 from 671 * |enableMacRandomization| + 2 from |setMeteredOverride| = 7 calls to |saveToStore| 672 */ 673 verify(mWifiConfigManager, times(7)).saveToStore(true); 674 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 675 verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); 676 verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class)); 677 assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); 678 verify(mWifiConfigManager).removeConnectChoiceFromAllNetworks(config.getUniqueId()); 679 680 // Verify content in the data source. 681 assertTrue(mUserDataSource.getProviders().isEmpty()); 682 // Removing a provider should not change the provider index. 683 assertEquals(1, mSharedDataSource.getProviderIndex()); 684 } 685 686 /** 687 * Verify that adding a user saved provider with a valid configuration and user credential will 688 * succeed. Remove provider using FQDN as key. 689 * 690 * @throws Exception 691 */ 692 @Test addRemoveByFqdnSavedProviderWithValidUserCredential()693 public void addRemoveByFqdnSavedProviderWithValidUserCredential() throws Exception { 694 addRemoveSavedProviderWithValidUserCredential(true); 695 } 696 697 /** 698 * Verify that adding a user saved provider with a valid configuration and user credential will 699 * succeed. Remove provider using unique identifier as key. 700 * 701 * @throws Exception 702 */ 703 @Test addRemoveByUniqueIdSavedProviderWithValidUserCredential()704 public void addRemoveByUniqueIdSavedProviderWithValidUserCredential() throws Exception { 705 addRemoveSavedProviderWithValidUserCredential(false); 706 } 707 708 /** 709 * Verify enable/disable autojoin on a provider. 710 * @param provider a mock provider that is already added into the PasspointManager 711 */ verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn)712 private void verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn) { 713 when(provider.setAutojoinEnabled(anyBoolean())).thenReturn(true); 714 if (useFqdn) { 715 assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(), 716 false)); 717 verify(provider).setAutojoinEnabled(false); 718 assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(), 719 true)); 720 verify(provider).setAutojoinEnabled(true); 721 assertFalse(mManager.enableAutojoin(null, provider.getConfig().getHomeSp() 722 .getFqdn() + "-XXXX", true)); 723 } else { 724 assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null, 725 false)); 726 verify(provider).setAutojoinEnabled(false); 727 assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null, 728 true)); 729 verify(provider).setAutojoinEnabled(true); 730 assertFalse( 731 mManager.enableAutojoin(provider.getConfig().getHomeSp().getFqdn() + "-XXXX", 732 null, true)); 733 } 734 verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF, 735 false, true); 736 verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON, 737 false, true); 738 } 739 740 /** 741 * Verify enable/disable mac randomization on a provider. 742 * @param provider a mock provider that is already added into the PasspointManager 743 */ verifyEnableMacRandomization(PasspointProvider provider)744 private void verifyEnableMacRandomization(PasspointProvider provider) { 745 when(provider.setMacRandomizationEnabled(anyBoolean())).thenReturn(true); 746 assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(), 747 false)); 748 verify(provider).setMacRandomizationEnabled(false); 749 verify(mWifiMetrics).logUserActionEvent( 750 UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF, false, true); 751 assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(), 752 true)); 753 verify(mWifiConfigManager, times(2)).removePasspointConfiguredNetwork( 754 provider.getWifiConfig().getProfileKey()); 755 verify(mWifiMetrics).logUserActionEvent( 756 UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON, false, true); 757 verify(provider).setMacRandomizationEnabled(true); 758 assertFalse(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn() 759 + "-XXXX", false)); 760 } 761 verifySetMeteredOverride(PasspointProvider provider)762 private void verifySetMeteredOverride(PasspointProvider provider) { 763 when(provider.setMeteredOverride(anyInt())).thenReturn(true); 764 assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(), 765 METERED_OVERRIDE_METERED)); 766 verify(provider).setMeteredOverride(METERED_OVERRIDE_METERED); 767 verify(mWifiMetrics).logUserActionEvent( 768 UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED, false, true); 769 assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(), 770 METERED_OVERRIDE_NOT_METERED)); 771 verify(provider).setMeteredOverride(METERED_OVERRIDE_NOT_METERED); 772 verify(mWifiMetrics).logUserActionEvent( 773 UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED, false, true); 774 assertFalse(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn() 775 + "-XXXX", METERED_OVERRIDE_METERED)); 776 } 777 778 /** 779 * Verify that adding a user saved provider with a valid configuration and SIM credential will 780 * succeed. 781 * 782 * @throws Exception 783 */ 784 @Test addRemoveSavedProviderWithValidSimCredential()785 public void addRemoveSavedProviderWithValidSimCredential() throws Exception { 786 PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 787 TEST_REALM); 788 PasspointProvider provider = createMockProvider(config); 789 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 790 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 791 eq(false), eq(mClock))).thenReturn(provider); 792 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 793 false, true)); 794 verifyInstalledConfig(config); 795 verify(mWifiConfigManager).saveToStore(true); 796 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 797 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 798 reset(mWifiMetrics); 799 reset(mWifiConfigManager); 800 801 // Verify content in the data source. 802 List<PasspointProvider> providers = mUserDataSource.getProviders(); 803 assertEquals(1, providers.size()); 804 assertEquals(config, providers.get(0).getConfig()); 805 // Provider index start with 0, should be 1 after adding a provider. 806 assertEquals(1, mSharedDataSource.getProviderIndex()); 807 808 // Remove the provider as a privileged non-creator app. 809 assertTrue(mManager.removeProvider(TEST_UID, true, null, TEST_FQDN)); 810 verify(provider).uninstallCertsAndKeys(); 811 verify(mWifiConfigManager).removePasspointConfiguredNetwork( 812 provider.getWifiConfig().getProfileKey()); 813 verify(mWifiConfigManager).saveToStore(true); 814 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 815 verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); 816 assertTrue(mManager.getProviderConfigs(TEST_UID, true).isEmpty()); 817 verify(mWifiConfigManager).removeConnectChoiceFromAllNetworks(config.getUniqueId()); 818 819 // Verify content in the data source. 820 assertTrue(mUserDataSource.getProviders().isEmpty()); 821 // Removing a provider should not change the provider index. 822 assertEquals(1, mSharedDataSource.getProviderIndex()); 823 } 824 825 /** 826 * Verify that if the passpoint profile has full IMSI, the carrier ID should be updated when 827 * the matched SIM card is present. 828 * @throws Exception 829 */ 830 @Test addProviderWithValidFullImsiOfSimCredential()831 public void addProviderWithValidFullImsiOfSimCredential() throws Exception { 832 PasspointConfiguration config = 833 createTestConfigWithSimCredential(TEST_FQDN, FULL_IMSI, TEST_REALM); 834 X509Certificate[] certArr = new X509Certificate[] {FakeKeys.CA_CERT0}; 835 config.getCredential().setCaCertificates(certArr); 836 SubscriptionInfo subInfo = mock(SubscriptionInfo.class); 837 when(subInfo.getSubscriptionId()).thenReturn(TEST_SUBID); 838 when(subInfo.getCarrierId()).thenReturn(TEST_CARRIER_ID); 839 TelephonyManager specifiedTm = mock(TelephonyManager.class); 840 when(mTelephonyManager.createForSubscriptionId(eq(TEST_SUBID))).thenReturn(specifiedTm); 841 when(specifiedTm.getSubscriberId()).thenReturn(FULL_IMSI); 842 when(specifiedTm.getSimApplicationState()).thenReturn(TelephonyManager.SIM_STATE_LOADED); 843 List<SubscriptionInfo> subInfoList = new ArrayList<SubscriptionInfo>() {{ 844 add(subInfo); 845 }}; 846 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfoList); 847 mSubscriptionsCaptor.getValue().onSubscriptionsChanged(); 848 when(mWifiKeyStore.putCaCertInKeyStore(any(String.class), any(Certificate.class))) 849 .thenReturn(true); 850 PasspointObjectFactory spyFactory = spy(new PasspointObjectFactory()); 851 when(mWifiNetworkSuggestionsManager.isPasspointSuggestionSharedWithUser(any())) 852 .thenReturn(true); 853 PasspointManager ut = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative, 854 mWifiKeyStore, mClock, spyFactory, mWifiConfigManager, 855 mWifiConfigStore, mWifiSettingsStore, mWifiMetrics, mWifiCarrierInfoManager, 856 mMacAddressUtil, mWifiPermissionsUtil); 857 858 assertTrue(ut.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 859 true, true)); 860 861 assertEquals(TEST_CARRIER_ID, config.getCarrierId()); 862 } 863 864 /** 865 * Verify that adding a user saved provider with the same base domain as the existing provider 866 * will succeed, and verify that the new provider with the new configuration is added. 867 * 868 * @throws Exception 869 */ 870 @Test addSavedProviderWithExistingConfig()871 public void addSavedProviderWithExistingConfig() throws Exception { 872 // Add a provider with the original configuration. 873 PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 874 TEST_REALM); 875 PasspointProvider origProvider = createMockProvider(origConfig); 876 when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore), 877 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 878 eq(false), eq(mClock))).thenReturn(origProvider); 879 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, 880 false, true)); 881 verifyInstalledConfig(origConfig); 882 verify(mWifiConfigManager).saveToStore(true); 883 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 884 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 885 verify(origProvider, never()).setUserConnectChoice(any(), anyInt()); 886 verify(origProvider, never()).setAutojoinEnabled(anyBoolean()); 887 verify(origProvider, never()).setAnonymousIdentity(any()); 888 reset(mWifiMetrics); 889 reset(mWifiConfigManager); 890 891 // Verify data source content. 892 List<PasspointProvider> origProviders = mUserDataSource.getProviders(); 893 assertEquals(1, origProviders.size()); 894 assertEquals(origConfig, origProviders.get(0).getConfig()); 895 assertEquals(1, mSharedDataSource.getProviderIndex()); 896 897 // Add same provider as existing suggestion provider 898 // This should be no WifiConfig deletion 899 WifiConfiguration origWifiConfig = origProvider.getWifiConfig(); 900 when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getProfileKey())) 901 .thenReturn(origWifiConfig); 902 when(mWifiConfigManager.addOrUpdateNetwork( 903 origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE, false)) 904 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); 905 when(origProvider.getAnonymousIdentity()).thenReturn(TEST_ANONYMOUS_IDENTITY); 906 when(origProvider.getConnectChoice()).thenReturn(USER_CONNECT_CHOICE); 907 when(origProvider.getConnectChoiceRssi()).thenReturn(TEST_RSSI); 908 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, 909 false, true)); 910 verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork( 911 origWifiConfig.getProfileKey()); 912 verify(mWifiConfigManager).addOrUpdateNetwork( 913 argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 914 eq(false)); 915 verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin); 916 verify(mWifiConfigManager).saveToStore(true); 917 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 918 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 919 assertEquals(2, mSharedDataSource.getProviderIndex()); 920 // Update provider will keep the user settings from the existing provider. 921 verify(origProvider).setUserConnectChoice(eq(USER_CONNECT_CHOICE), eq(TEST_RSSI)); 922 verify(origProvider).setAnonymousIdentity(eq(TEST_ANONYMOUS_IDENTITY)); 923 reset(mWifiMetrics); 924 reset(mWifiConfigManager); 925 926 // Add another provider with the same base domain as the existing provider. 927 // This should replace the existing provider with the new configuration. 928 PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN, 929 TEST_FRIENDLY_NAME); 930 PasspointProvider newProvider = createMockProvider(newConfig); 931 when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore), 932 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 933 eq(false), eq(mClock))).thenReturn(newProvider); 934 when(mWifiConfigManager.getConfiguredNetwork(origProvider.getWifiConfig() 935 .getProfileKey())).thenReturn(origWifiConfig); 936 assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, 937 false, true)); 938 939 List<PasspointConfiguration> installedConfigs = 940 mManager.getProviderConfigs(TEST_CREATOR_UID, true); 941 assertEquals(2, installedConfigs.size()); 942 assertTrue(installedConfigs.contains(origConfig)); 943 assertTrue(installedConfigs.contains(newConfig)); 944 945 verify(mWifiConfigManager).saveToStore(true); 946 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 947 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 948 949 // Verify data source content. 950 List<PasspointProvider> newProviders = mUserDataSource.getProviders(); 951 assertEquals(2, newProviders.size()); 952 assertTrue(newConfig.equals(newProviders.get(0).getConfig()) 953 || newConfig.equals(newProviders.get(1).getConfig())); 954 assertEquals(3, mSharedDataSource.getProviderIndex()); 955 } 956 957 /** 958 * Verify that adding a provider will fail when failing to install certificates and 959 * key to the keystore. 960 * 961 * @throws Exception 962 */ 963 @Test addProviderOnKeyInstallationFailiure()964 public void addProviderOnKeyInstallationFailiure() throws Exception { 965 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 966 TEST_FRIENDLY_NAME); 967 PasspointProvider provider = mock(PasspointProvider.class); 968 when(provider.installCertsAndKeys()).thenReturn(false); 969 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), eq( 970 mWifiCarrierInfoManager), 971 anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false), 972 eq(mClock))).thenReturn(provider); 973 assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 974 false, true)); 975 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 976 verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); 977 } 978 979 /** 980 * Verify that adding a provider with R1 configuration and a private self-signed CA certificate 981 * is installed correctly. 982 * 983 * @throws Exception 984 */ 985 @Test addProviderWithR1ConfigPrivateCaCert()986 public void addProviderWithR1ConfigPrivateCaCert() throws Exception { 987 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 988 TEST_FRIENDLY_NAME); 989 PasspointProvider provider = createMockProvider(config); 990 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 991 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 992 eq(false), eq(mClock))).thenReturn(provider); 993 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 994 false, true)); 995 verifyInstalledConfig(config); 996 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 997 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 998 } 999 1000 /** 1001 * Verify that adding a provider with R2 configuration will not perform CA certificate 1002 * verification. 1003 * 1004 * @throws Exception 1005 */ 1006 @Test addProviderWithR2Config()1007 public void addProviderWithR2Config() throws Exception { 1008 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 1009 TEST_FRIENDLY_NAME); 1010 config.setUpdateIdentifier(1); 1011 PasspointProvider provider = createMockProvider(config); 1012 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1013 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 1014 eq(false), eq(mClock))).thenReturn(provider); 1015 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 1016 false, true)); 1017 verifyInstalledConfig(config); 1018 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 1019 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 1020 } 1021 1022 /** 1023 * Verify that removing a non-existing provider will fail. 1024 * 1025 * @throws Exception 1026 */ 1027 @Test removeNonExistingProvider()1028 public void removeNonExistingProvider() throws Exception { 1029 assertFalse(mManager.removeProvider(TEST_CREATOR_UID, true, null, TEST_FQDN)); 1030 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 1031 verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); 1032 } 1033 1034 /** 1035 * Verify that a empty list will be returned when no providers are installed. 1036 * 1037 * @throws Exception 1038 */ 1039 @Test matchProviderWithNoProvidersInstalled()1040 public void matchProviderWithNoProvidersInstalled() throws Exception { 1041 assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty()); 1042 } 1043 1044 /** 1045 * Verify that a {code null} be returned when ANQP entry doesn't exist in the cache. 1046 * 1047 * @throws Exception 1048 */ 1049 @Test matchProviderWithAnqpCacheMissed()1050 public void matchProviderWithAnqpCacheMissed() throws Exception { 1051 // static mocking 1052 MockitoSession session = 1053 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 1054 InformationElementUtil.class).startMocking(); 1055 try { 1056 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1057 1058 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 1059 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1060 vsa.hsRelease = NetworkDetail.HSRelease.R1; 1061 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1062 InformationElementUtil.RoamingConsortium roamingConsortium = 1063 new InformationElementUtil.RoamingConsortium(); 1064 roamingConsortium.anqpOICount = 0; 1065 when(InformationElementUtil.getRoamingConsortiumIE(isNull())) 1066 .thenReturn(roamingConsortium); 1067 assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty()); 1068 // Verify that a request for ANQP elements is initiated. 1069 verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), 1070 any(ANQPNetworkKey.class), 1071 anyBoolean(), any(NetworkDetail.HSRelease.class)); 1072 } finally { 1073 session.finishMocking(); 1074 } 1075 } 1076 1077 /** 1078 * Verify that the expected provider will be returned when a HomeProvider is matched. 1079 * 1080 * @throws Exception 1081 */ 1082 @Test matchProviderAsHomeProvider()1083 public void matchProviderAsHomeProvider() throws Exception { 1084 PasspointProvider provider = 1085 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1086 ANQPData entry = new ANQPData(mClock, null); 1087 1088 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 1089 when(provider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 1090 .thenReturn(PasspointMatch.HomeProvider); 1091 List<Pair<PasspointProvider, PasspointMatch>> results = 1092 mManager.matchProvider(createTestScanResult()); 1093 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 1094 assertEquals(PasspointMatch.HomeProvider, result.second); 1095 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 1096 } 1097 1098 /** 1099 * Verify that the expected provider will be returned when a RoamingProvider is matched. 1100 * 1101 * @throws Exception 1102 */ 1103 @Test matchProviderAsRoamingProvider()1104 public void matchProviderAsRoamingProvider() throws Exception { 1105 PasspointProvider provider = 1106 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1107 ANQPData entry = new ANQPData(mClock, null); 1108 1109 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 1110 when(provider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 1111 .thenReturn(PasspointMatch.RoamingProvider); 1112 List<Pair<PasspointProvider, PasspointMatch>> results = 1113 mManager.matchProvider(createTestScanResult()); 1114 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 1115 assertEquals(PasspointMatch.RoamingProvider, result.second); 1116 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 1117 } 1118 1119 /** 1120 * Verify that a {code null} will be returned when there is no matching provider. 1121 * 1122 * @throws Exception 1123 */ 1124 @Test matchProviderWithNoMatch()1125 public void matchProviderWithNoMatch() throws Exception { 1126 PasspointProvider provider = 1127 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1128 ANQPData entry = new ANQPData(mClock, null); 1129 1130 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 1131 when(provider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 1132 .thenReturn(PasspointMatch.None); 1133 assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty()); 1134 } 1135 1136 /** 1137 * Verify the expectations for sweepCache. 1138 * 1139 * @throws Exception 1140 */ 1141 @Test sweepCache()1142 public void sweepCache() throws Exception { 1143 mManager.sweepCache(); 1144 verify(mAnqpCache).sweep(); 1145 } 1146 1147 /** 1148 * Verify that an empty map will be returned if ANQP elements are not cached for the given AP. 1149 * 1150 * @throws Exception 1151 */ 1152 @Test getANQPElementsWithNoMatchFound()1153 public void getANQPElementsWithNoMatchFound() throws Exception { 1154 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 1155 assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty()); 1156 } 1157 1158 /** 1159 * Verify that an expected ANQP elements will be returned if ANQP elements are cached for the 1160 * given AP. 1161 * 1162 * @throws Exception 1163 */ 1164 @Test getANQPElementsWithMatchFound()1165 public void getANQPElementsWithMatchFound() throws Exception { 1166 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 1167 anqpElementMap.put(ANQPElementType.ANQPDomName, 1168 new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); 1169 ANQPData entry = new ANQPData(mClock, anqpElementMap); 1170 1171 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 1172 assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult())); 1173 } 1174 1175 /** 1176 * Verify that if the Carrier ID is updated during match, the config should be persisted. 1177 */ 1178 @Test getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential()1179 public void getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential() { 1180 // static mocking 1181 MockitoSession session = 1182 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 1183 InformationElementUtil.class).startMocking(); 1184 try { 1185 PasspointProvider provider = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME, 1186 TEST_PACKAGE, false, null, false); 1187 when(provider.tryUpdateCarrierId()).thenReturn(true); 1188 reset(mWifiConfigManager); 1189 1190 ANQPData entry = new ANQPData(mClock, null); 1191 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1192 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2; 1193 1194 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry); 1195 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1196 when(provider.match(anyMap(), isNull(), any(ScanResult.class))) 1197 .thenReturn(PasspointMatch.HomeProvider); 1198 1199 List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = 1200 mManager.getAllMatchedProviders(createTestScanResult()); 1201 1202 verify(mWifiConfigManager).saveToStore(eq(true)); 1203 1204 } finally { 1205 session.finishMocking(); 1206 } 1207 } 1208 /** 1209 * Verify that an expected map of FQDN and a list of ScanResult will be returned when provided 1210 * scanResults are matched to installed Passpoint profiles. 1211 */ 1212 @Test getAllMatchingFqdnsForScanResults()1213 public void getAllMatchingFqdnsForScanResults() { 1214 // static mocking 1215 MockitoSession session = 1216 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 1217 InformationElementUtil.class).startMocking(); 1218 try { 1219 PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME, 1220 TEST_PACKAGE, false, null, false); 1221 providerHome.getWifiConfig().isHomeProviderNetwork = true; 1222 PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME, 1223 TEST_PACKAGE, false, null, false); 1224 WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1, 1225 TEST_UID, "\"PasspointTestSSID\"", true, true, 1226 TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP); 1227 PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 1228 TEST_PACKAGE, wifiConfiguration, false, null, false); 1229 ANQPData entry = new ANQPData(mClock, null); 1230 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1231 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2; 1232 1233 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry); 1234 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1235 when(providerHome.match(anyMap(), isNull(), any(ScanResult.class))) 1236 .thenReturn(PasspointMatch.HomeProvider); 1237 when(providerRoaming.match(anyMap(), isNull(), any(ScanResult.class))) 1238 .thenReturn(PasspointMatch.RoamingProvider); 1239 when(providerNone.match(anyMap(), isNull(), any(ScanResult.class))) 1240 .thenReturn(PasspointMatch.None); 1241 1242 Map<String, Map<Integer, List<ScanResult>>> configs = 1243 mManager.getAllMatchingPasspointProfilesForScanResults( 1244 createTestScanResults()); 1245 1246 // Expects to be matched with home Provider for each AP (two APs). 1247 assertEquals(2, configs.get(providerHome.getConfig().getUniqueId()).get( 1248 WifiManager.PASSPOINT_HOME_NETWORK).size()); 1249 assertFalse(configs.get(providerHome.getConfig().getUniqueId()) 1250 .containsKey(WifiManager.PASSPOINT_ROAMING_NETWORK)); 1251 1252 // Expects to be matched with roaming Provider for each AP (two APs). 1253 assertEquals(2, configs.get(providerRoaming.getConfig().getUniqueId()).get( 1254 WifiManager.PASSPOINT_ROAMING_NETWORK).size()); 1255 assertFalse(configs.get(providerRoaming.getConfig().getUniqueId()) 1256 .containsKey(WifiManager.PASSPOINT_HOME_NETWORK)); 1257 1258 } finally { 1259 session.finishMocking(); 1260 } 1261 } 1262 1263 /** 1264 * Verify that an expected list of {@link WifiConfiguration} will be returned when provided 1265 * a list of FQDN is matched to installed Passpoint profiles which is already added into the 1266 * WifiConfigManager. For suggestion passpoint network, will check if that suggestion share 1267 * credential with user to choose from wifi picker. 1268 * - Provider1 and Provider2 are saved passpoint, Provider1 is already added into the 1269 * WifiConfigManger 1270 * - Provider3 and Provider4 are suggestion passpoint, only Provider4 is shared with user. Both 1271 * providers are already added into the WifiConfigManager 1272 * - Expected result: Provider1 and Provider4 should be returned . 1273 */ 1274 @Test getWifiConfigsForPasspointProfiles()1275 public void getWifiConfigsForPasspointProfiles() { 1276 PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 1277 TEST_PACKAGE, false, null, false); 1278 WifiConfiguration config1 = provider1.getWifiConfig(); 1279 when(mWifiConfigManager.getConfiguredNetwork(provider1.getConfig().getUniqueId())) 1280 .thenReturn(config1); 1281 PasspointProvider provider2 = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME, 1282 TEST_PACKAGE, false, null, false); 1283 PasspointProvider provider3 = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 1284 TEST_PACKAGE, true, null, false); 1285 when(mWifiNetworkSuggestionsManager 1286 .isPasspointSuggestionSharedWithUser(provider3.getWifiConfig())).thenReturn(false); 1287 WifiConfiguration config3 = provider3.getWifiConfig(); 1288 when(mWifiConfigManager.getConfiguredNetwork(provider3.getConfig().getUniqueId())) 1289 .thenReturn(config3); 1290 PasspointProvider provider4 = addTestProvider(TEST_FQDN + 3, TEST_FRIENDLY_NAME, 1291 TEST_PACKAGE, true, null, false); 1292 when(mWifiNetworkSuggestionsManager 1293 .isPasspointSuggestionSharedWithUser(provider4.getWifiConfig())).thenReturn(true); 1294 WifiConfiguration config4 = provider4.getWifiConfig(); 1295 when(mWifiConfigManager.getConfiguredNetwork(provider4.getConfig().getUniqueId())) 1296 .thenReturn(config4); 1297 1298 List<WifiConfiguration> wifiConfigurationList = mManager.getWifiConfigsForPasspointProfiles( 1299 List.of(provider1.getConfig().getUniqueId(), provider2.getConfig().getUniqueId(), 1300 provider3.getConfig().getUniqueId(), provider4.getConfig().getUniqueId(), 1301 TEST_FQDN + "_353ab8c93", TEST_FQDN + "_83765319aca")); 1302 assertEquals(2, wifiConfigurationList.size()); 1303 Set<String> uniqueIdSet = wifiConfigurationList 1304 .stream() 1305 .map(WifiConfiguration::getPasspointUniqueId) 1306 .collect(Collectors.toSet()); 1307 assertTrue(uniqueIdSet.contains(provider1.getConfig().getUniqueId())); 1308 assertTrue(uniqueIdSet.contains(provider4.getConfig().getUniqueId())); 1309 } 1310 1311 /** 1312 * Verify that a {@link WifiConfiguration} will be returned with the correct value for the 1313 * randomized MAC address. 1314 */ 1315 @Test getWifiConfigsForPasspointProfilesWithoutNonPersistentMacRandomization()1316 public void getWifiConfigsForPasspointProfilesWithoutNonPersistentMacRandomization() { 1317 MacAddress randomizedMacAddress = MacAddress.fromString("01:23:45:67:89:ab"); 1318 when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(randomizedMacAddress); 1319 when(mWifiConfigManager.shouldUseNonPersistentRandomization(any())).thenReturn(false); 1320 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 1321 TEST_PACKAGE, false, null, false); 1322 WifiConfiguration configuration = provider.getWifiConfig(); 1323 when(mWifiConfigManager.getConfiguredNetwork(provider.getConfig().getUniqueId())) 1324 .thenReturn(configuration); 1325 WifiConfiguration config = mManager.getWifiConfigsForPasspointProfiles( 1326 Collections.singletonList(provider.getConfig().getUniqueId())).get(0); 1327 assertEquals(config.getRandomizedMacAddress(), randomizedMacAddress); 1328 verify(mMacAddressUtil).calculatePersistentMac( 1329 eq(provider.getConfig().getUniqueId()), any()); 1330 } 1331 1332 /** 1333 * Verify that a {@link WifiConfiguration} will be returned with DEFAULT_MAC_ADDRESS for the 1334 * randomized MAC address if non-persistent mac randomization is enabled. This value will 1335 * display in the wifi picker's network details page as "Not available" if the network is 1336 * disconnected. 1337 */ 1338 @Test getWifiConfigsForPasspointProfilesWithNonPersistentMacRandomization()1339 public void getWifiConfigsForPasspointProfilesWithNonPersistentMacRandomization() { 1340 MacAddress randomizedMacAddress = MacAddress.fromString("01:23:45:67:89:ab"); 1341 when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(randomizedMacAddress); 1342 when(mWifiConfigManager.shouldUseNonPersistentRandomization(any())).thenReturn(true); 1343 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 1344 TEST_PACKAGE, false, null, false); 1345 WifiConfiguration configuration = provider.getWifiConfig(); 1346 when(mWifiConfigManager.getConfiguredNetwork(provider.getConfig().getUniqueId())) 1347 .thenReturn(configuration); 1348 WifiConfiguration config = mManager.getWifiConfigsForPasspointProfiles( 1349 Collections.singletonList(provider.getConfig().getUniqueId())).get(0); 1350 assertEquals(config.getRandomizedMacAddress(), MacAddress.fromString(DEFAULT_MAC_ADDRESS)); 1351 } 1352 1353 /** 1354 * Verify that an empty map will be returned when trying to get all matching FQDN for a {@code 1355 * null} {@link ScanResult}. 1356 */ 1357 @Test getAllMatchingFqdnsForScanResultsWithNullScanResult()1358 public void getAllMatchingFqdnsForScanResultsWithNullScanResult() throws Exception { 1359 assertEquals(0, 1360 mManager.getAllMatchingPasspointProfilesForScanResults(null).size()); 1361 } 1362 1363 /** 1364 * Verify that an empty map will be returned when trying to get a all matching FQDN for a {@link 1365 * ScanResult} with a {@code null} BSSID. 1366 */ 1367 @Test getAllMatchingFqdnsForScanResultsWithNullBSSID()1368 public void getAllMatchingFqdnsForScanResultsWithNullBSSID() throws Exception { 1369 ScanResult scanResult = createTestScanResult(); 1370 scanResult.BSSID = null; 1371 1372 assertEquals(0, 1373 mManager.getAllMatchingPasspointProfilesForScanResults( 1374 Arrays.asList(scanResult)).size()); 1375 } 1376 1377 /** 1378 * Verify that an empty map will be returned when trying to get all matching FQDN for a {@link 1379 * ScanResult} with an invalid BSSID. 1380 */ 1381 @Test ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID()1382 public void ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID() throws Exception { 1383 ScanResult scanResult = createTestScanResult(); 1384 scanResult.BSSID = "asdfdasfas"; 1385 1386 assertEquals(0, 1387 mManager.getAllMatchingPasspointProfilesForScanResults( 1388 Arrays.asList(scanResult)).size()); 1389 } 1390 1391 /** 1392 * Verify that an empty map will be returned when trying to get all matching FQDN for a 1393 * non-Passpoint AP. 1394 */ 1395 @Test getAllMatchingFqdnsForScanResultsForNonPasspointAP()1396 public void getAllMatchingFqdnsForScanResultsForNonPasspointAP() throws Exception { 1397 ScanResult scanResult = createTestScanResult(); 1398 scanResult.flags = 0; 1399 assertEquals(0, 1400 mManager.getAllMatchingPasspointProfilesForScanResults( 1401 Arrays.asList(scanResult)).size()); 1402 } 1403 1404 /** 1405 * Verify that an empty list will be returned when retrieving OSU providers for an AP with 1406 * null scan result. 1407 * 1408 * @throws Exception 1409 */ 1410 @Test getMatchingOsuProvidersForNullScanResult()1411 public void getMatchingOsuProvidersForNullScanResult() throws Exception { 1412 assertTrue(mManager.getMatchingOsuProviders(null).isEmpty()); 1413 } 1414 1415 /** 1416 * Verify that an empty list will be returned when retrieving OSU providers for an AP with 1417 * invalid BSSID. 1418 * 1419 * @throws Exception 1420 */ 1421 @Test getMatchingOsuProvidersForInvalidBSSID()1422 public void getMatchingOsuProvidersForInvalidBSSID() throws Exception { 1423 ScanResult scanResult = createTestScanResult(); 1424 scanResult.BSSID = "asdfdasfas"; 1425 assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty()); 1426 } 1427 1428 /** 1429 * Verify that an empty list will be returned when retrieving OSU providers for a 1430 * non-Passpoint AP. 1431 * 1432 * @throws Exception 1433 */ 1434 @Test getMatchingOsuProvidersForNonPasspointAP()1435 public void getMatchingOsuProvidersForNonPasspointAP() throws Exception { 1436 ScanResult scanResult = createTestScanResult(); 1437 scanResult.flags = 0; 1438 assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty()); 1439 } 1440 1441 /** 1442 * Verify that an empty list will be returned when no match is found from the ANQP cache. 1443 * 1444 * @throws Exception 1445 */ 1446 @Test getMatchingOsuProviderWithNoMatch()1447 public void getMatchingOsuProviderWithNoMatch() throws Exception { 1448 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 1449 assertTrue( 1450 mManager.getMatchingOsuProviders(Arrays.asList(createTestScanResult())).isEmpty()); 1451 } 1452 1453 /** 1454 * Verify that an expected provider list will be returned when a match is found from 1455 * the ANQP cache with a given list of scanResult. 1456 * 1457 * @throws Exception 1458 */ 1459 @Test getMatchingOsuProvidersWithMatch()1460 public void getMatchingOsuProvidersWithMatch() throws Exception { 1461 // Setup OSU providers ANQP element for AP1. 1462 List<OsuProviderInfo> providerInfoListOfAp1 = new ArrayList<>(); 1463 Map<ANQPElementType, ANQPElement> anqpElementMapOfAp1 = new HashMap<>(); 1464 Set<OsuProvider> expectedOsuProvidersForDomainId = new HashSet<>(); 1465 1466 // Setup OSU providers ANQP element for AP2. 1467 List<OsuProviderInfo> providerInfoListOfAp2 = new ArrayList<>(); 1468 Map<ANQPElementType, ANQPElement> anqpElementMapOfAp2 = new HashMap<>(); 1469 Set<OsuProvider> expectedOsuProvidersForDomainId2 = new HashSet<>(); 1470 int osuProviderCount = 4; 1471 1472 // static mocking 1473 MockitoSession session = 1474 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 1475 InformationElementUtil.class).startMocking(); 1476 try { 1477 for (int i = 0; i < osuProviderCount; i++) { 1478 // Test data. 1479 String friendlyName = "Test Provider" + i; 1480 String serviceDescription = "Dummy Service" + i; 1481 Uri serverUri = Uri.parse("https://" + "test" + i + ".com"); 1482 String nai = "access.test.com"; 1483 List<Integer> methodList = Arrays.asList(1); 1484 List<I18Name> friendlyNames = Arrays.asList( 1485 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, friendlyName)); 1486 List<I18Name> serviceDescriptions = Arrays.asList( 1487 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, 1488 serviceDescription)); 1489 Map<String, String> friendlyNameMap = new HashMap<>(); 1490 friendlyNames.forEach(e -> friendlyNameMap.put(e.getLanguage(), e.getText())); 1491 1492 expectedOsuProvidersForDomainId.add(new OsuProvider( 1493 (WifiSsid) null, friendlyNameMap, serviceDescription, 1494 serverUri, nai, methodList)); 1495 1496 // add All OSU Providers for AP1. 1497 providerInfoListOfAp1.add(new OsuProviderInfo( 1498 friendlyNames, serverUri, methodList, null, nai, serviceDescriptions)); 1499 1500 // add only half of All OSU Providers for AP2. 1501 if (i >= osuProviderCount / 2) { 1502 providerInfoListOfAp2.add(new OsuProviderInfo( 1503 friendlyNames, serverUri, methodList, null, nai, serviceDescriptions)); 1504 expectedOsuProvidersForDomainId2.add(new OsuProvider( 1505 (WifiSsid) null, friendlyNameMap, serviceDescription, 1506 serverUri, nai, methodList)); 1507 } 1508 } 1509 anqpElementMapOfAp1.put(ANQPElementType.HSOSUProviders, 1510 new HSOsuProvidersElement(WifiSsid.fromUtf8Text("Test SSID"), 1511 providerInfoListOfAp1)); 1512 ANQPData anqpData = new ANQPData(mClock, anqpElementMapOfAp1); 1513 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(anqpData); 1514 1515 anqpElementMapOfAp2.put(ANQPElementType.HSOSUProviders, 1516 new HSOsuProvidersElement(WifiSsid.fromUtf8Text("Test SSID2"), 1517 providerInfoListOfAp2)); 1518 ANQPData anqpData2 = new ANQPData(mClock, anqpElementMapOfAp2); 1519 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(anqpData2); 1520 1521 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 1522 1523 // ANQP_DOMAIN_ID(TEST_ANQP_KEY) 1524 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 1525 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1526 assertEquals(mManager.getMatchingOsuProviders( 1527 Arrays.asList(createTestScanResult())).keySet(), 1528 expectedOsuProvidersForDomainId); 1529 1530 // ANQP_DOMAIN_ID2(TEST_ANQP_KEY2) 1531 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2; 1532 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 1533 assertEquals(mManager.getMatchingOsuProviders( 1534 createTestScanResults()).keySet(), expectedOsuProvidersForDomainId2); 1535 } finally { 1536 session.finishMocking(); 1537 } 1538 } 1539 1540 /** 1541 * Verify that matching Passpoint configurations will be returned as map with corresponding 1542 * OSU providers. 1543 */ 1544 @Test getMatchingPasspointConfigsForOsuProvidersWithMatch()1545 public void getMatchingPasspointConfigsForOsuProvidersWithMatch() { 1546 PasspointProvider provider1 = 1547 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, true); 1548 PasspointProvider provider2 = 1549 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null, true); 1550 1551 List<OsuProvider> osuProviders = new ArrayList<>(); 1552 Map<String, String> friendlyNames = new HashMap<>(); 1553 friendlyNames.put("en", "NO-MATCH-NAME"); 1554 friendlyNames.put("kr", TEST_FRIENDLY_NAME + 1); 1555 1556 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1557 friendlyNames)); 1558 friendlyNames = new HashMap<>(); 1559 friendlyNames.put("en", TEST_FRIENDLY_NAME2); 1560 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1561 friendlyNames)); 1562 1563 Map<OsuProvider, PasspointConfiguration> results = 1564 mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders); 1565 1566 assertEquals(2, results.size()); 1567 assertThat(Arrays.asList(provider1.getConfig(), provider2.getConfig()), 1568 containsInAnyOrder(results.values().toArray())); 1569 } 1570 1571 /** 1572 * Verify that empty map will be returned when there is no matching Passpoint configuration. 1573 */ 1574 @Test getMatchingPasspointConfigsForOsuProvidersWitNoMatch()1575 public void getMatchingPasspointConfigsForOsuProvidersWitNoMatch() { 1576 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1577 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null, false); 1578 1579 List<OsuProvider> osuProviders = new ArrayList<>(); 1580 1581 Map<String, String> friendlyNames = new HashMap<>(); 1582 friendlyNames.put("en", "NO-MATCH-NAME"); 1583 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1584 friendlyNames)); 1585 friendlyNames = new HashMap<>(); 1586 friendlyNames.put("en", "NO-MATCH-NAME-2"); 1587 osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true, 1588 friendlyNames)); 1589 1590 assertEquals(0, mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders).size()); 1591 } 1592 1593 /** 1594 * Verify that the provider list maintained by the PasspointManager after the list is updated 1595 * in the data source. 1596 * 1597 * @throws Exception 1598 */ 1599 @Test verifyProvidersAfterDataSourceUpdate()1600 public void verifyProvidersAfterDataSourceUpdate() throws Exception { 1601 // Update the provider list in the data source. 1602 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 1603 TEST_FRIENDLY_NAME); 1604 PasspointProvider provider = createMockProvider(config); 1605 List<PasspointProvider> providers = new ArrayList<>(); 1606 providers.add(provider); 1607 mUserDataSource.setProviders(providers); 1608 1609 // Verify the providers maintained by PasspointManager. 1610 assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size()); 1611 assertEquals(config, mManager.getProviderConfigs(TEST_CREATOR_UID, true).get(0)); 1612 } 1613 1614 /** 1615 * Verify that the provider index used by PasspointManager is updated after it is updated in 1616 * the data source. 1617 * 1618 * @throws Exception 1619 */ 1620 @Test verifyProviderIndexAfterDataSourceUpdate()1621 public void verifyProviderIndexAfterDataSourceUpdate() throws Exception { 1622 long providerIndex = 9; 1623 mSharedDataSource.setProviderIndex(providerIndex); 1624 assertEquals(providerIndex, mSharedDataSource.getProviderIndex()); 1625 1626 // Add a provider. 1627 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 1628 TEST_FRIENDLY_NAME); 1629 PasspointProvider provider = createMockProvider(config); 1630 // Verify the provider ID used to create the new provider. 1631 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1632 eq(mWifiCarrierInfoManager), eq(providerIndex), eq(TEST_CREATOR_UID), 1633 eq(TEST_PACKAGE), eq(false), eq(mClock))).thenReturn(provider); 1634 1635 assertTrue( 1636 mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false, true)); 1637 verifyInstalledConfig(config); 1638 reset(mWifiConfigManager); 1639 } 1640 1641 /** 1642 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1643 * adding a legacy Passpoint configuration containing a valid user credential. 1644 * 1645 * @throws Exception 1646 */ 1647 @Test addLegacyPasspointConfigWithUserCredential()1648 public void addLegacyPasspointConfigWithUserCredential() throws Exception { 1649 // Test data. 1650 String fqdn = "test.com"; 1651 String friendlyName = "Friendly Name"; 1652 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1653 String realm = "realm.com"; 1654 String username = "username"; 1655 String password = "password"; 1656 byte[] base64EncodedPw = 1657 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 1658 String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8); 1659 String caCertificateAlias = "CaCert"; 1660 1661 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1662 WifiConfiguration wifiConfig = new WifiConfiguration(); 1663 wifiConfig.FQDN = fqdn; 1664 wifiConfig.providerFriendlyName = friendlyName; 1665 wifiConfig.roamingConsortiumIds = rcOIs; 1666 wifiConfig.enterpriseConfig.setIdentity(username); 1667 wifiConfig.enterpriseConfig.setPassword(password); 1668 wifiConfig.enterpriseConfig.setRealm(realm); 1669 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); 1670 wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP); 1671 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1672 1673 // Setup expected {@link PasspointConfiguration} 1674 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1675 HomeSp homeSp = new HomeSp(); 1676 homeSp.setFqdn(fqdn); 1677 homeSp.setFriendlyName(friendlyName); 1678 homeSp.setRoamingConsortiumOis(rcOIs); 1679 passpointConfig.setHomeSp(homeSp); 1680 Credential credential = new Credential(); 1681 Credential.UserCredential userCredential = new Credential.UserCredential(); 1682 userCredential.setUsername(username); 1683 userCredential.setPassword(encodedPasswordStr); 1684 userCredential.setEapType(EAPConstants.EAP_TTLS); 1685 userCredential.setNonEapInnerMethod("PAP"); 1686 credential.setUserCredential(userCredential); 1687 credential.setRealm(realm); 1688 passpointConfig.setCredential(credential); 1689 1690 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1691 verifyInstalledConfig(passpointConfig); 1692 } 1693 1694 /** 1695 * Verify that adding a legacy Passpoint configuration containing user credential will 1696 * fail when client certificate is not provided. 1697 * 1698 * @throws Exception 1699 */ 1700 @Test addLegacyPasspointConfigWithUserCredentialWithoutCaCert()1701 public void addLegacyPasspointConfigWithUserCredentialWithoutCaCert() throws Exception { 1702 // Test data. 1703 String fqdn = "test.com"; 1704 String friendlyName = "Friendly Name"; 1705 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1706 String realm = "realm.com"; 1707 String username = "username"; 1708 String password = "password"; 1709 byte[] base64EncodedPw = 1710 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 1711 String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8); 1712 1713 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1714 WifiConfiguration wifiConfig = new WifiConfiguration(); 1715 wifiConfig.FQDN = fqdn; 1716 wifiConfig.providerFriendlyName = friendlyName; 1717 wifiConfig.roamingConsortiumIds = rcOIs; 1718 wifiConfig.enterpriseConfig.setIdentity(username); 1719 wifiConfig.enterpriseConfig.setPassword(password); 1720 wifiConfig.enterpriseConfig.setRealm(realm); 1721 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); 1722 wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP); 1723 1724 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1725 } 1726 1727 /** 1728 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1729 * adding a legacy Passpoint configuration containing a valid SIM credential. 1730 * 1731 * @throws Exception 1732 */ 1733 @Test addLegacyPasspointConfigWithSimCredential()1734 public void addLegacyPasspointConfigWithSimCredential() throws Exception { 1735 // Test data. 1736 String fqdn = "test.com"; 1737 String friendlyName = "Friendly Name"; 1738 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1739 String realm = "realm.com"; 1740 String imsi = "1234"; 1741 1742 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1743 WifiConfiguration wifiConfig = new WifiConfiguration(); 1744 wifiConfig.FQDN = fqdn; 1745 wifiConfig.providerFriendlyName = friendlyName; 1746 wifiConfig.roamingConsortiumIds = rcOIs; 1747 wifiConfig.enterpriseConfig.setRealm(realm); 1748 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 1749 wifiConfig.enterpriseConfig.setPlmn(imsi); 1750 1751 // Setup expected {@link PasspointConfiguration} 1752 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1753 HomeSp homeSp = new HomeSp(); 1754 homeSp.setFqdn(fqdn); 1755 homeSp.setFriendlyName(friendlyName); 1756 homeSp.setRoamingConsortiumOis(rcOIs); 1757 passpointConfig.setHomeSp(homeSp); 1758 Credential credential = new Credential(); 1759 Credential.SimCredential simCredential = new Credential.SimCredential(); 1760 simCredential.setEapType(EAPConstants.EAP_SIM); 1761 simCredential.setImsi(imsi); 1762 credential.setSimCredential(simCredential); 1763 credential.setRealm(realm); 1764 passpointConfig.setCredential(credential); 1765 1766 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1767 verifyInstalledConfig(passpointConfig); 1768 } 1769 1770 /** 1771 * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when 1772 * adding a legacy Passpoint configuration containing a valid certificate credential. 1773 * 1774 * @throws Exception 1775 */ 1776 @Test addLegacyPasspointConfigWithCertCredential()1777 public void addLegacyPasspointConfigWithCertCredential() throws Exception { 1778 // Test data. 1779 String fqdn = "test.com"; 1780 String friendlyName = "Friendly Name"; 1781 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1782 String realm = "realm.com"; 1783 String caCertificateAlias = "CaCert"; 1784 String clientCertificateAlias = "ClientCert"; 1785 1786 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1787 WifiConfiguration wifiConfig = new WifiConfiguration(); 1788 wifiConfig.FQDN = fqdn; 1789 wifiConfig.providerFriendlyName = friendlyName; 1790 wifiConfig.roamingConsortiumIds = rcOIs; 1791 wifiConfig.enterpriseConfig.setRealm(realm); 1792 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1793 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1794 wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias); 1795 1796 // Setup expected {@link PasspointConfiguration} 1797 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1798 HomeSp homeSp = new HomeSp(); 1799 homeSp.setFqdn(fqdn); 1800 homeSp.setFriendlyName(friendlyName); 1801 homeSp.setRoamingConsortiumOis(rcOIs); 1802 passpointConfig.setHomeSp(homeSp); 1803 Credential credential = new Credential(); 1804 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 1805 certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3); 1806 credential.setCertCredential(certCredential); 1807 credential.setRealm(realm); 1808 passpointConfig.setCredential(credential); 1809 1810 assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1811 verifyInstalledConfig(passpointConfig); 1812 } 1813 1814 /** 1815 * Verify that adding a legacy Passpoint configuration containing certificate credential will 1816 * fail when CA certificate is not provided. 1817 * 1818 * @throws Exception 1819 */ 1820 @Test addLegacyPasspointConfigWithCertCredentialWithoutCaCert()1821 public void addLegacyPasspointConfigWithCertCredentialWithoutCaCert() throws Exception { 1822 // Test data. 1823 String fqdn = "test.com"; 1824 String friendlyName = "Friendly Name"; 1825 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1826 String realm = "realm.com"; 1827 String clientCertificateAlias = "ClientCert"; 1828 1829 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1830 WifiConfiguration wifiConfig = new WifiConfiguration(); 1831 wifiConfig.FQDN = fqdn; 1832 wifiConfig.providerFriendlyName = friendlyName; 1833 wifiConfig.roamingConsortiumIds = rcOIs; 1834 wifiConfig.enterpriseConfig.setRealm(realm); 1835 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1836 wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias); 1837 1838 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1839 } 1840 1841 /** 1842 * Verify that adding a legacy Passpoint configuration containing certificate credential will 1843 * fail when client certificate is not provided. 1844 * 1845 * @throws Exception 1846 */ 1847 @Test addLegacyPasspointConfigWithCertCredentialWithoutClientCert()1848 public void addLegacyPasspointConfigWithCertCredentialWithoutClientCert() throws Exception { 1849 // Test data. 1850 String fqdn = "test.com"; 1851 String friendlyName = "Friendly Name"; 1852 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 1853 String realm = "realm.com"; 1854 String caCertificateAlias = "CaCert"; 1855 1856 // Setup WifiConfiguration for legacy Passpoint configuraiton. 1857 WifiConfiguration wifiConfig = new WifiConfiguration(); 1858 wifiConfig.FQDN = fqdn; 1859 wifiConfig.providerFriendlyName = friendlyName; 1860 wifiConfig.roamingConsortiumIds = rcOIs; 1861 wifiConfig.enterpriseConfig.setRealm(realm); 1862 wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1863 wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias); 1864 1865 assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig)); 1866 } 1867 1868 /** 1869 * Verify that the provider's "hasEverConnected" flag will be set to true and the associated 1870 * metric is updated after the provider was used to successfully connect to a Passpoint 1871 * network for the first time. 1872 * 1873 * @throws Exception 1874 */ 1875 @Test providerNetworkConnectedFirstTime()1876 public void providerNetworkConnectedFirstTime() throws Exception { 1877 PasspointProvider provider = 1878 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1879 when(provider.getHasEverConnected()).thenReturn(false); 1880 mManager.onPasspointNetworkConnected(provider.getConfig().getUniqueId()); 1881 verify(provider).setHasEverConnected(eq(true)); 1882 } 1883 1884 /** 1885 * Verify that the provider's "hasEverConnected" flag the associated metric is not updated 1886 * after the provider was used to successfully connect to a Passpoint network for non-first 1887 * time. 1888 * 1889 * @throws Exception 1890 */ 1891 @Test providerNetworkConnectedNotFirstTime()1892 public void providerNetworkConnectedNotFirstTime() throws Exception { 1893 PasspointProvider provider = 1894 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1895 when(provider.getHasEverConnected()).thenReturn(true); 1896 mManager.onPasspointNetworkConnected(TEST_FQDN); 1897 verify(provider, never()).setHasEverConnected(anyBoolean()); 1898 } 1899 1900 /** 1901 * Verify that the expected Passpoint metrics are updated when 1902 * {@link PasspointManager#updateMetrics} is invoked. 1903 * 1904 * @throws Exception 1905 */ 1906 @Test updateMetrics()1907 public void updateMetrics() { 1908 PasspointProvider provider = 1909 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1910 ArgumentCaptor<Map<String, PasspointProvider>> argCaptor = ArgumentCaptor.forClass( 1911 Map.class); 1912 // Provider have not provided a successful network connection. 1913 int expectedInstalledProviders = 1; 1914 int expectedConnectedProviders = 0; 1915 when(provider.getHasEverConnected()).thenReturn(false); 1916 mManager.updateMetrics(); 1917 verify(mWifiMetrics).updateSavedPasspointProfiles( 1918 eq(expectedInstalledProviders), eq(expectedConnectedProviders)); 1919 1920 verify(mWifiMetrics).updateSavedPasspointProfilesInfo(argCaptor.capture()); 1921 assertEquals(expectedInstalledProviders, argCaptor.getValue().size()); 1922 assertEquals(provider, argCaptor.getValue().get(provider.getConfig().getUniqueId())); 1923 reset(mWifiMetrics); 1924 1925 // Provider have provided a successful network connection. 1926 expectedConnectedProviders = 1; 1927 when(provider.getHasEverConnected()).thenReturn(true); 1928 mManager.updateMetrics(); 1929 verify(mWifiMetrics).updateSavedPasspointProfiles( 1930 eq(expectedInstalledProviders), eq(expectedConnectedProviders)); 1931 } 1932 1933 /** 1934 * Verify Passpoint Manager's provisioning APIs by invoking methods in PasspointProvisioner for 1935 * initiailization and provisioning a provider. 1936 */ 1937 @Test verifyPasspointProvisioner()1938 public void verifyPasspointProvisioner() { 1939 mManager.initializeProvisioner(mLooper.getLooper()); 1940 verify(mPasspointProvisioner).init(any(Looper.class)); 1941 when(mPasspointProvisioner.startSubscriptionProvisioning(anyInt(), any(OsuProvider.class), 1942 any(IProvisioningCallback.class))).thenReturn(true); 1943 OsuProvider osuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 1944 assertEquals(true, 1945 mManager.startSubscriptionProvisioning(TEST_UID, osuProvider, mCallback)); 1946 } 1947 1948 /** 1949 * Verify that the corresponding Passpoint provider is removed when the app is disabled. 1950 */ 1951 @Test verifyRemovingPasspointProfilesWhenAppIsDisabled()1952 public void verifyRemovingPasspointProfilesWhenAppIsDisabled() { 1953 WifiConfiguration currentConfiguration = WifiConfigurationTestUtil.createPasspointNetwork(); 1954 currentConfiguration.FQDN = TEST_FQDN; 1955 PasspointProvider passpointProvider = 1956 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 1957 currentConfiguration.setPasspointUniqueId(passpointProvider.getConfig().getUniqueId()); 1958 verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), 1959 mAppOpChangedListenerCaptor.capture()); 1960 assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size()); 1961 AppOpsManager.OnOpChangedListener listener = mAppOpChangedListenerCaptor.getValue(); 1962 assertNotNull(listener); 1963 1964 // Disallow change wifi state & ensure we remove the profiles from database. 1965 when(mAppOpsManager.unsafeCheckOpNoThrow( 1966 OPSTR_CHANGE_WIFI_STATE, TEST_CREATOR_UID, 1967 TEST_PACKAGE)) 1968 .thenReturn(MODE_IGNORED); 1969 listener.onOpChanged(OPSTR_CHANGE_WIFI_STATE, TEST_PACKAGE); 1970 mLooper.dispatchAll(); 1971 1972 verify(mAppOpsManager).stopWatchingMode(mAppOpChangedListenerCaptor.getValue()); 1973 verify(mWifiConfigManager).removePasspointConfiguredNetwork( 1974 passpointProvider.getWifiConfig().getProfileKey()); 1975 assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, true).isEmpty()); 1976 } 1977 1978 /** 1979 * Verify that removing a provider with a different UID will not succeed. 1980 * 1981 * @throws Exception 1982 */ 1983 @Test removeGetProviderWithDifferentUid()1984 public void removeGetProviderWithDifferentUid() throws Exception { 1985 PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 1986 TEST_REALM); 1987 PasspointProvider provider = createMockProvider(config); 1988 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 1989 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 1990 eq(false), eq(mClock))).thenReturn(provider); 1991 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 1992 false, true)); 1993 verifyInstalledConfig(config); 1994 verify(mWifiConfigManager).saveToStore(true); 1995 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 1996 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 1997 reset(mWifiMetrics); 1998 reset(mWifiConfigManager); 1999 2000 // no profiles available for TEST_UID 2001 assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty()); 2002 // 1 profile available for TEST_CREATOR_UID 2003 assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); 2004 2005 // Remove the provider as a non-privileged non-creator app. 2006 assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN)); 2007 verify(provider, never()).uninstallCertsAndKeys(); 2008 verify(mWifiConfigManager, never()).saveToStore(true); 2009 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 2010 verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); 2011 2012 // no profiles available for TEST_UID 2013 assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty()); 2014 // 1 profile available for TEST_CREATOR_UID 2015 assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); 2016 } 2017 2018 /** 2019 * Verify that removing a provider from a background user will fail. 2020 * 2021 * @throws Exception 2022 */ 2023 @Test removeProviderWithBackgroundUser()2024 public void removeProviderWithBackgroundUser() throws Exception { 2025 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 2026 TEST_FRIENDLY_NAME); 2027 PasspointProvider provider = createMockProvider(config); 2028 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2029 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2030 eq(false), eq(mClock))).thenReturn(provider); 2031 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 2032 false, true)); 2033 verifyInstalledConfig(config); 2034 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2035 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2036 2037 when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt())) 2038 .thenReturn(false); 2039 assertFalse(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN)); 2040 } 2041 2042 /** 2043 * Verify that adding a suggestion provider with a valid configuration and user credential will 2044 * succeed. 2045 * 2046 * @throws Exception 2047 */ 2048 @Test addRemoveSuggestionProvider()2049 public void addRemoveSuggestionProvider() throws Exception { 2050 PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, 2051 TEST_FRIENDLY_NAME); 2052 PasspointProvider provider = createMockProvider(config); 2053 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2054 when(provider.isFromSuggestion()).thenReturn(true); 2055 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2056 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2057 eq(true), eq(mClock))).thenReturn(provider); 2058 assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, 2059 true, true)); 2060 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2061 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2062 verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), 2063 eq(TEST_PACKAGE), any(AppOpsManager.OnOpChangedListener.class)); 2064 assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); 2065 reset(mWifiMetrics); 2066 reset(mWifiConfigManager); 2067 2068 // Verify content in the data source. 2069 List<PasspointProvider> providers = mUserDataSource.getProviders(); 2070 assertEquals(1, providers.size()); 2071 assertEquals(config, providers.get(0).getConfig()); 2072 // Provider index start with 0, should be 1 after adding a provider. 2073 assertEquals(1, mSharedDataSource.getProviderIndex()); 2074 2075 // Remove from another Suggestor app, should fail. 2076 assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN)); 2077 verify(provider, never()).uninstallCertsAndKeys(); 2078 verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork( 2079 provider.getWifiConfig().getProfileKey()); 2080 verify(mWifiConfigManager, never()).saveToStore(true); 2081 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 2082 verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); 2083 verify(mAppOpsManager, never()).stopWatchingMode( 2084 any(AppOpsManager.OnOpChangedListener.class)); 2085 // Verify content in the data source. 2086 providers = mUserDataSource.getProviders(); 2087 assertEquals(1, providers.size()); 2088 assertEquals(config, providers.get(0).getConfig()); 2089 // Provider index start with 0, should be 1 after adding a provider. 2090 assertEquals(1, mSharedDataSource.getProviderIndex()); 2091 reset(mWifiMetrics); 2092 reset(mWifiConfigManager); 2093 2094 // Remove the provider from same app. 2095 assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN)); 2096 verify(provider).uninstallCertsAndKeys(); 2097 verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork( 2098 provider.getWifiConfig().getProfileKey()); 2099 verify(mWifiConfigManager, never()).saveToStore(true); 2100 verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); 2101 verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); 2102 verify(mAppOpsManager, never()).stopWatchingMode( 2103 any(AppOpsManager.OnOpChangedListener.class)); 2104 verify(mWifiConfigManager).removeConnectChoiceFromAllNetworks(config.getUniqueId()); 2105 2106 // Verify content in the data source. 2107 assertTrue(mUserDataSource.getProviders().isEmpty()); 2108 // Removing a provider should not change the provider index. 2109 assertEquals(1, mSharedDataSource.getProviderIndex()); 2110 } 2111 2112 /** 2113 * Verify that adding a suggestion provider with the same base domain as the existing 2114 * suggestion provider from same app will succeed, and verify that the new provider is 2115 * added along with the existing provider. 2116 * 2117 * @throws Exception 2118 */ 2119 @Test addSuggestionProviderWithExistingConfig()2120 public void addSuggestionProviderWithExistingConfig() throws Exception { 2121 // Add a provider with the original configuration. 2122 PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 2123 TEST_REALM); 2124 PasspointProvider origProvider = createMockProvider(origConfig); 2125 when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE); 2126 when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore), 2127 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2128 eq(true), eq(mClock))).thenReturn(origProvider); 2129 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, 2130 true, true)); 2131 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2132 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2133 reset(mWifiMetrics); 2134 reset(mWifiConfigManager); 2135 2136 // Verify data source content. 2137 List<PasspointProvider> origProviders = mUserDataSource.getProviders(); 2138 assertEquals(1, origProviders.size()); 2139 assertEquals(origConfig, origProviders.get(0).getConfig()); 2140 assertEquals(1, mSharedDataSource.getProviderIndex()); 2141 2142 // Add same provider as existing suggestion provider 2143 // This should be no WifiConfig deletion 2144 WifiConfiguration origWifiConfig = origProvider.getWifiConfig(); 2145 origWifiConfig.fromWifiNetworkSuggestion = true; 2146 origWifiConfig.creatorUid = TEST_CREATOR_UID; 2147 origWifiConfig.creatorName = TEST_PACKAGE; 2148 when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getProfileKey())) 2149 .thenReturn(origWifiConfig); 2150 when(mWifiConfigManager.addOrUpdateNetwork( 2151 origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE, false)) 2152 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); 2153 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, 2154 true, true)); 2155 verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork( 2156 origWifiConfig.getProfileKey()); 2157 verify(mWifiConfigManager).addOrUpdateNetwork( 2158 argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2159 eq(false)); 2160 verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin); 2161 verify(mWifiConfigManager, never()).saveToStore(true); 2162 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2163 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2164 assertEquals(2, mSharedDataSource.getProviderIndex()); 2165 reset(mWifiMetrics); 2166 reset(mWifiConfigManager); 2167 2168 // Add another provider with the same base domain as the existing saved provider. 2169 // This should replace the existing provider with the new configuration. 2170 PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN, 2171 TEST_FRIENDLY_NAME); 2172 PasspointProvider newProvider = createMockProvider(newConfig); 2173 when(newProvider.isFromSuggestion()).thenReturn(true); 2174 when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE); 2175 when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore), 2176 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2177 eq(true), eq(mClock))).thenReturn(newProvider); 2178 assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, 2179 true, true)); 2180 verify(mWifiConfigManager, never()).saveToStore(true); 2181 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2182 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2183 2184 // Verify data source content. 2185 List<PasspointProvider> newProviders = mUserDataSource.getProviders(); 2186 assertEquals(2, newProviders.size()); 2187 assertTrue(newConfig.equals(newProviders.get(0).getConfig()) 2188 || newConfig.equals(newProviders.get(1).getConfig())); 2189 assertTrue(origConfig.equals(newProviders.get(0).getConfig()) 2190 || origConfig.equals(newProviders.get(1).getConfig())); 2191 assertEquals(3, mSharedDataSource.getProviderIndex()); 2192 } 2193 2194 /** 2195 * Verify that adding a saved provider with the same base domain as the existing 2196 * suggestion provider will succeed, and verify that the new provider with the new configuration 2197 * is added along with the existing provider. 2198 * 2199 * @throws Exception 2200 */ 2201 @Test addSavedProviderWithExistingSuggestionConfig()2202 public void addSavedProviderWithExistingSuggestionConfig() throws Exception { 2203 // Add a provider with the original configuration. 2204 PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 2205 TEST_REALM); 2206 PasspointProvider origProvider = createMockProvider(origConfig); 2207 when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE); 2208 when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore), 2209 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2210 eq(true), eq(mClock))).thenReturn(origProvider); 2211 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, 2212 true, true)); 2213 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2214 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2215 reset(mWifiMetrics); 2216 reset(mWifiConfigManager); 2217 2218 // Verify data source content. 2219 List<PasspointProvider> origProviders = mUserDataSource.getProviders(); 2220 assertEquals(1, origProviders.size()); 2221 assertEquals(origConfig, origProviders.get(0).getConfig()); 2222 assertEquals(1, mSharedDataSource.getProviderIndex()); 2223 2224 // Add another provider with the same base domain as the existing saved provider. 2225 // This should replace the existing provider with the new configuration. 2226 PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN, 2227 TEST_FRIENDLY_NAME); 2228 PasspointProvider newProvider = createMockProvider(newConfig); 2229 when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore), 2230 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2231 eq(false), eq(mClock))).thenReturn(newProvider); 2232 assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, 2233 false, true)); 2234 verify(mWifiConfigManager).saveToStore(true); 2235 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2236 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2237 2238 // Verify data source content. 2239 List<PasspointProvider> newProviders = mUserDataSource.getProviders(); 2240 assertEquals(2, newProviders.size()); 2241 assertTrue(newConfig.equals(newProviders.get(0).getConfig()) 2242 || newConfig.equals(newProviders.get(1).getConfig())); 2243 assertTrue(origConfig.equals(newProviders.get(0).getConfig()) 2244 || origConfig.equals(newProviders.get(1).getConfig())); 2245 assertEquals(2, mSharedDataSource.getProviderIndex()); 2246 } 2247 2248 /** 2249 * Verify that adding a suggestion provider with the same base domain as the existing provider 2250 * from different apps will add a new provider. 2251 * 2252 * @throws Exception 2253 */ 2254 @Test addSuggestionProviderWithExistingConfigFromDifferentSource()2255 public void addSuggestionProviderWithExistingConfigFromDifferentSource() throws Exception { 2256 // Add a provider with the original configuration. 2257 PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, 2258 TEST_REALM); 2259 PasspointProvider origProvider = createMockProvider(origConfig); 2260 when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE); 2261 when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore), 2262 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2263 eq(false), eq(mClock))).thenReturn(origProvider); 2264 assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false, 2265 true)); 2266 verifyInstalledConfig(origConfig); 2267 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2268 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2269 reset(mWifiMetrics); 2270 reset(mWifiConfigManager); 2271 2272 // Verify data source content. 2273 List<PasspointProvider> origProviders = mUserDataSource.getProviders(); 2274 assertEquals(1, origProviders.size()); 2275 assertEquals(origConfig, origProviders.get(0).getConfig()); 2276 assertEquals(1, mSharedDataSource.getProviderIndex()); 2277 2278 // Add another provider with the same base domain as the existing saved provider but from 2279 // different app. This should not replace the existing provider with the new configuration 2280 // but add another one. 2281 PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN, 2282 TEST_FRIENDLY_NAME); 2283 PasspointProvider newProvider = createMockProvider(newConfig); 2284 when(newProvider.isFromSuggestion()).thenReturn(true); 2285 when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE1); 2286 when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore), 2287 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1), 2288 eq(true), eq(mClock))).thenReturn(newProvider); 2289 assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE1, true, 2290 true)); 2291 verify(mWifiConfigManager, never()).saveToStore(true); 2292 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2293 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2294 2295 // Verify data source content. 2296 List<PasspointProvider> newProviders = mUserDataSource.getProviders(); 2297 assertEquals(2, newProviders.size()); 2298 assertTrue(origConfig.equals(newProviders.get(0).getConfig()) 2299 || origConfig.equals(newProviders.get(1).getConfig())); 2300 2301 assertEquals(2, mSharedDataSource.getProviderIndex()); 2302 } 2303 2304 /** 2305 * Verify that the HomeProvider provider will be returned when a HomeProvider profile has 2306 * not expired and RoamingProvider expiration is unset (still valid). 2307 * 2308 * @throws Exception 2309 */ 2310 @Test matchHomeProviderWhenHomeProviderNotExpired()2311 public void matchHomeProviderWhenHomeProviderNotExpired() throws Exception { 2312 // static mocking 2313 MockitoSession session = 2314 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2315 InformationElementUtil.class).startMocking(); 2316 try { 2317 PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2318 TEST_PACKAGE, false, null, false); 2319 providerHome.getConfig().setSubscriptionExpirationTimeInMillis( 2320 System.currentTimeMillis() + 100000); 2321 providerHome.getWifiConfig().isHomeProviderNetwork = true; 2322 PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME, 2323 TEST_PACKAGE, false, null, false); 2324 WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1, 2325 TEST_UID, "\"PasspointTestSSID\"", true, true, 2326 TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP); 2327 PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 2328 TEST_PACKAGE, wifiConfiguration, false, null, false); 2329 ANQPData entry = new ANQPData(mClock, null); 2330 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2331 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 2332 2333 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2334 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2335 when(providerHome.match(anyMap(), isNull(), any(ScanResult.class))) 2336 .thenReturn(PasspointMatch.HomeProvider); 2337 when(providerRoaming.match(anyMap(), isNull(), any(ScanResult.class))) 2338 .thenReturn(PasspointMatch.RoamingProvider); 2339 when(providerNone.match(anyMap(), isNull(), any(ScanResult.class))) 2340 .thenReturn(PasspointMatch.None); 2341 2342 List<Pair<PasspointProvider, PasspointMatch>> results = 2343 mManager.matchProvider(createTestScanResult()); 2344 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 2345 2346 assertEquals(PasspointMatch.HomeProvider, result.second); 2347 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 2348 2349 } finally { 2350 session.finishMocking(); 2351 } 2352 } 2353 2354 /** 2355 * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has 2356 * expired and RoamingProvider expiration is unset (still valid). 2357 * 2358 * @throws Exception 2359 */ 2360 @Test matchRoamingProviderUnsetWhenHomeProviderExpired()2361 public void matchRoamingProviderUnsetWhenHomeProviderExpired() throws Exception { 2362 // static mocking 2363 MockitoSession session = 2364 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2365 InformationElementUtil.class).startMocking(); 2366 try { 2367 PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2368 TEST_PACKAGE, false, null, false); 2369 providerHome.getConfig().setSubscriptionExpirationTimeInMillis( 2370 System.currentTimeMillis() - 10000); 2371 providerHome.getWifiConfig().isHomeProviderNetwork = true; 2372 PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME, 2373 TEST_PACKAGE, false, null, false); 2374 WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1, 2375 TEST_UID, "\"PasspointTestSSID\"", true, true, 2376 TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP); 2377 PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 2378 TEST_PACKAGE, wifiConfiguration, false, null, false); 2379 ANQPData entry = new ANQPData(mClock, null); 2380 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2381 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 2382 2383 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2384 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2385 when(providerHome.match(anyMap(), isNull(), any(ScanResult.class))) 2386 .thenReturn(PasspointMatch.HomeProvider); 2387 when(providerRoaming.match(anyMap(), isNull(), any(ScanResult.class))) 2388 .thenReturn(PasspointMatch.RoamingProvider); 2389 when(providerNone.match(anyMap(), isNull(), any(ScanResult.class))) 2390 .thenReturn(PasspointMatch.None); 2391 2392 List<Pair<PasspointProvider, PasspointMatch>> results = 2393 mManager.matchProvider(createTestScanResult()); 2394 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 2395 2396 assertEquals(PasspointMatch.RoamingProvider, result.second); 2397 assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn()); 2398 2399 } finally { 2400 session.finishMocking(); 2401 } 2402 } 2403 2404 /** 2405 * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has 2406 * expired and RoamingProvider expiration is still valid. 2407 * 2408 * @throws Exception 2409 */ 2410 @Test matchRoamingProviderNonExpiredWhenHomeProviderExpired()2411 public void matchRoamingProviderNonExpiredWhenHomeProviderExpired() throws Exception { 2412 // static mocking 2413 MockitoSession session = 2414 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2415 InformationElementUtil.class).startMocking(); 2416 try { 2417 PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2418 TEST_PACKAGE, false, null, false); 2419 providerHome.getConfig().setSubscriptionExpirationTimeInMillis( 2420 System.currentTimeMillis() - 10000); 2421 providerHome.getWifiConfig().isHomeProviderNetwork = true; 2422 PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME, 2423 TEST_PACKAGE, false, null, false); 2424 providerRoaming.getConfig().setSubscriptionExpirationTimeInMillis( 2425 System.currentTimeMillis() + 100000); 2426 WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1, 2427 TEST_UID, "\"PasspointTestSSID\"", true, true, 2428 TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP); 2429 PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME, 2430 TEST_PACKAGE, wifiConfiguration, false, null, false); 2431 ANQPData entry = new ANQPData(mClock, null); 2432 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2433 vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID; 2434 2435 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2436 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2437 when(providerHome.match(anyMap(), isNull(), any(ScanResult.class))) 2438 .thenReturn(PasspointMatch.HomeProvider); 2439 when(providerRoaming.match(anyMap(), isNull(), any(ScanResult.class))) 2440 .thenReturn(PasspointMatch.RoamingProvider); 2441 when(providerNone.match(anyMap(), isNull(), any(ScanResult.class))) 2442 .thenReturn(PasspointMatch.None); 2443 2444 List<Pair<PasspointProvider, PasspointMatch>> results = 2445 mManager.matchProvider(createTestScanResult()); 2446 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 2447 2448 assertEquals(PasspointMatch.RoamingProvider, result.second); 2449 assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn()); 2450 2451 } finally { 2452 session.finishMocking(); 2453 } 2454 } 2455 2456 /** 2457 * Verify add untrusted passpoint network from suggestion success. 2458 */ 2459 @Test testAddUntrustedPasspointNetworkFromSuggestion()2460 public void testAddUntrustedPasspointNetworkFromSuggestion() { 2461 WifiConfiguration wifiConfig = new WifiConfiguration(); 2462 wifiConfig.FQDN = TEST_FQDN; 2463 PasspointConfiguration config = 2464 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME); 2465 PasspointProvider provider = createMockProvider(config, wifiConfig, true); 2466 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2467 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2468 eq(true), eq(mClock))).thenReturn(provider); 2469 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2470 assertTrue(mManager.addOrUpdateProvider( 2471 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false)); 2472 verify(provider).setTrusted(false); 2473 } 2474 2475 /** 2476 * Verify add untrusted passpoint network not from suggestion fail. 2477 */ 2478 @Test testAddUntrustedPasspointNetworkNotFromSuggestion()2479 public void testAddUntrustedPasspointNetworkNotFromSuggestion() { 2480 WifiConfiguration wifiConfig = new WifiConfiguration(); 2481 wifiConfig.FQDN = TEST_FQDN; 2482 PasspointConfiguration config = 2483 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME); 2484 PasspointProvider provider = createMockProvider(config, wifiConfig, false); 2485 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2486 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2487 eq(true), eq(mClock))).thenReturn(provider); 2488 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2489 assertFalse(mManager.addOrUpdateProvider( 2490 config, TEST_CREATOR_UID, TEST_PACKAGE, false, false)); 2491 verify(provider, never()).setTrusted(false); 2492 } 2493 2494 /** 2495 * Verify that the ScanResults(Access Points) are returned when it may be 2496 * authenticated with the provided passpoint configuration as roaming match. 2497 */ 2498 @Test getMatchingScanResultsTestWithRoamingMatch()2499 public void getMatchingScanResultsTestWithRoamingMatch() { 2500 PasspointConfiguration config = mock(PasspointConfiguration.class); 2501 PasspointProvider mockProvider = mock(PasspointProvider.class); 2502 when(mObjectFactory.makePasspointProvider(config, null, 2503 mWifiCarrierInfoManager, 0, 0, null, false, mClock)) 2504 .thenReturn(mockProvider); 2505 List<ScanResult> scanResults = new ArrayList<>() {{ 2506 add(mock(ScanResult.class)); 2507 }}; 2508 when(mockProvider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 2509 .thenReturn(PasspointMatch.RoamingProvider); 2510 2511 List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults); 2512 2513 assertEquals(1, testResults.size()); 2514 } 2515 2516 /** 2517 * Verify that the ScanResults(Access Points) are returned when it may be 2518 * authenticated with the provided passpoint configuration as home match. 2519 */ 2520 @Test getMatchingScanResultsTestWithHomeMatch()2521 public void getMatchingScanResultsTestWithHomeMatch() { 2522 PasspointConfiguration config = mock(PasspointConfiguration.class); 2523 PasspointProvider mockProvider = mock(PasspointProvider.class); 2524 when(mObjectFactory.makePasspointProvider(config, null, 2525 mWifiCarrierInfoManager, 0, 0, null, false, mClock)) 2526 .thenReturn(mockProvider); 2527 List<ScanResult> scanResults = new ArrayList<>() {{ 2528 add(mock(ScanResult.class)); 2529 }}; 2530 when(mockProvider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 2531 .thenReturn(PasspointMatch.HomeProvider); 2532 2533 List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults); 2534 2535 assertEquals(1, testResults.size()); 2536 } 2537 2538 /** 2539 * Verify that the ScanResults(Access Points) are not returned when it cannot be 2540 * authenticated with the provided passpoint configuration as none match. 2541 */ 2542 @Test getMatchingScanResultsTestWithNonMatch()2543 public void getMatchingScanResultsTestWithNonMatch() { 2544 PasspointConfiguration config = mock(PasspointConfiguration.class); 2545 2546 PasspointProvider mockProvider = mock(PasspointProvider.class); 2547 2548 when(mObjectFactory.makePasspointProvider(config, null, 2549 mWifiCarrierInfoManager, 0, 0, null, false, mClock)) 2550 .thenReturn(mockProvider); 2551 2552 List<ScanResult> scanResults = new ArrayList<>() {{ 2553 add(mock(ScanResult.class)); 2554 }}; 2555 when(mockProvider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 2556 .thenReturn(PasspointMatch.None); 2557 2558 List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults); 2559 2560 assertEquals(0, testResults.size()); 2561 } 2562 2563 /** 2564 * Verify that no ANQP queries are requested when not allowed (i.e. by WifiMetrics) when 2565 * there is a cache miss. 2566 */ 2567 @Test testAnqpRequestNotAllowed()2568 public void testAnqpRequestNotAllowed() { 2569 reset(mWifiConfigManager); 2570 when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(null); 2571 verify(mAnqpRequestManager, never()).requestANQPElements(any(long.class), 2572 any(ANQPNetworkKey.class), any(boolean.class), any(NetworkDetail.HSRelease.class)); 2573 } 2574 2575 /** 2576 * Verify that removing of multiple providers with the same FQDN is done correctly. 2577 */ 2578 @Test removeAllProvidersWithSameFqdn()2579 public void removeAllProvidersWithSameFqdn() { 2580 PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2581 TEST_PACKAGE, false, TEST_REALM, false); 2582 PasspointProvider provider2 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2583 TEST_PACKAGE, false, TEST_REALM2, false); 2584 PasspointProvider provider3 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2585 TEST_PACKAGE, false, TEST_REALM3, false); 2586 2587 List<PasspointProvider> providers = mUserDataSource.getProviders(); 2588 assertEquals(3, providers.size()); 2589 verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallation(); 2590 verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallSuccess(); 2591 2592 // Remove the provider as the creator app. 2593 assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN)); 2594 2595 verify(provider1).uninstallCertsAndKeys(); 2596 verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork( 2597 provider1.getWifiConfig().getProfileKey()); 2598 verify(provider2).uninstallCertsAndKeys(); 2599 verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork( 2600 provider2.getWifiConfig().getProfileKey()); 2601 verify(provider3).uninstallCertsAndKeys(); 2602 verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork( 2603 provider3.getWifiConfig().getProfileKey()); 2604 2605 verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallation(); 2606 verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallSuccess(); 2607 verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class)); 2608 assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); 2609 verify(mWifiConfigManager, times(3)).removeConnectChoiceFromAllNetworks(any()); 2610 2611 // Verify content in the data source. 2612 assertTrue(mUserDataSource.getProviders().isEmpty()); 2613 } 2614 2615 /** 2616 * Verify that adding a provider with a self signed root CA increments the metrics correctly. 2617 * 2618 * @throws Exception 2619 */ 2620 @Test verifySelfSignRootCaMetrics()2621 public void verifySelfSignRootCaMetrics() throws Exception { 2622 WifiConfiguration wifiConfig = new WifiConfiguration(); 2623 wifiConfig.FQDN = TEST_FQDN; 2624 PasspointConfiguration config = 2625 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME); 2626 PasspointProvider provider = createMockProvider(config, wifiConfig, true); 2627 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2628 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2629 eq(true), eq(mClock))).thenReturn(provider); 2630 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2631 assertTrue(mManager.addOrUpdateProvider( 2632 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false)); 2633 verify(mWifiMetrics).incrementNumPasspointProviderWithSelfSignedRootCa(); 2634 verify(mWifiMetrics, never()).incrementNumPasspointProviderWithNoRootCa(); 2635 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2636 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2637 } 2638 2639 /** 2640 * Verify that adding a provider with no root CA increments the metrics correctly. 2641 * 2642 * @throws Exception 2643 */ 2644 @Test verifyNoRootCaMetrics()2645 public void verifyNoRootCaMetrics() throws Exception { 2646 WifiConfiguration wifiConfig = new WifiConfiguration(); 2647 wifiConfig.FQDN = TEST_FQDN; 2648 PasspointConfiguration config = 2649 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME); 2650 config.getCredential().setCaCertificate(null); 2651 PasspointProvider provider = createMockProvider(config, wifiConfig, true); 2652 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2653 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2654 eq(true), eq(mClock))).thenReturn(provider); 2655 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2656 assertTrue(mManager.addOrUpdateProvider( 2657 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false)); 2658 verify(mWifiMetrics).incrementNumPasspointProviderWithNoRootCa(); 2659 verify(mWifiMetrics, never()).incrementNumPasspointProviderWithSelfSignedRootCa(); 2660 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2661 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2662 } 2663 2664 /** 2665 * Verify that adding a provider with subscription expiration increments the metrics correctly. 2666 * 2667 * @throws Exception 2668 */ 2669 @Test verifySubscriptionExpirationMetrics()2670 public void verifySubscriptionExpirationMetrics() throws Exception { 2671 WifiConfiguration wifiConfig = new WifiConfiguration(); 2672 wifiConfig.FQDN = TEST_FQDN; 2673 PasspointConfiguration config = 2674 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME); 2675 config.setSubscriptionExpirationTimeInMillis(1586228641000L); 2676 PasspointProvider provider = createMockProvider(config, wifiConfig, true); 2677 when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), 2678 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), 2679 eq(true), eq(mClock))).thenReturn(provider); 2680 when(provider.getPackageName()).thenReturn(TEST_PACKAGE); 2681 assertTrue(mManager.addOrUpdateProvider( 2682 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false)); 2683 verify(mWifiMetrics).incrementNumPasspointProviderWithSubscriptionExpiration(); 2684 verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); 2685 verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); 2686 } 2687 2688 /** 2689 * Verify that venue URL ANQP request is sent correctly. 2690 * 2691 * @throws Exception 2692 */ 2693 @Test verifyRequestVenueUrlAnqpElement()2694 public void verifyRequestVenueUrlAnqpElement() throws Exception { 2695 // static mocking 2696 MockitoSession session = 2697 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2698 InformationElementUtil.class).startMocking(); 2699 try { 2700 ScanResult scanResult = createTestScanResult(); 2701 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2702 vsa.anqpDomainID = scanResult.anqpDomainId; 2703 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2704 long bssid = Utils.parseMac(scanResult.BSSID); 2705 mManager.requestVenueUrlAnqpElement(scanResult); 2706 verify(mAnqpRequestManager).requestVenueUrlAnqpElement(eq(bssid), any()); 2707 } finally { 2708 session.finishMocking(); 2709 } 2710 } 2711 2712 /** 2713 * Verify blocking a matched provider following a Deauthentication-imminent WNM-notification 2714 */ 2715 @Test testBlockingProvider()2716 public void testBlockingProvider() { 2717 WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(10, TEST_UID, 2718 "\"PasspointTestSSID\"", true, true, TEST_FQDN, 2719 TEST_FRIENDLY_NAME, SECURITY_EAP); 2720 wifiConfig.BSSID = TEST_BSSID_STRING; 2721 2722 PasspointProvider provider = 2723 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, wifiConfig, false, 2724 null, false); 2725 WnmData event = WnmData.createDeauthImminentEvent(Utils.parseMac(TEST_BSSID_STRING), "", 2726 true, 30); 2727 2728 mManager.handleDeauthImminentEvent(event, wifiConfig); 2729 verify(provider).blockBssOrEss(eq(event.getBssid()), eq(event.isEss()), 2730 eq(event.getDelay())); 2731 } 2732 2733 /** 2734 * Verify set Anonymous Identity to the right passpoint provider. 2735 */ 2736 @Test testSetAnonymousIdentity()2737 public void testSetAnonymousIdentity() { 2738 WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(10, TEST_UID, 2739 "\"PasspointTestSSID\"", true, true, TEST_FQDN, 2740 TEST_FRIENDLY_NAME, SECURITY_EAP); 2741 2742 PasspointProvider provider = 2743 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, wifiConfig, false, 2744 null, false); 2745 2746 wifiConfig.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY); 2747 mManager.setAnonymousIdentity(wifiConfig); 2748 verify(provider).setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY); 2749 2750 2751 mManager.resetSimPasspointNetwork(); 2752 verify(provider).setAnonymousIdentity(null); 2753 verify(mWifiConfigManager, times(3)).saveToStore(true); 2754 } 2755 2756 /** 2757 * Test set and remove user connect choice. 2758 */ 2759 @Test testSetUserConnectChoice()2760 public void testSetUserConnectChoice() { 2761 WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(10, TEST_UID, 2762 "\"PasspointTestSSID\"", true, true, TEST_FQDN, 2763 TEST_FRIENDLY_NAME, SECURITY_EAP); 2764 2765 PasspointProvider provider = 2766 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, wifiConfig, false, 2767 null, false); 2768 2769 WifiConfiguration wifiConfig2 = WifiConfigurationTestUtil.generateWifiConfig(11, TEST_UID, 2770 "\"PasspointTestSSID\"", true, true, TEST_FQDN2, 2771 TEST_FRIENDLY_NAME, SECURITY_EAP); 2772 2773 PasspointProvider provider2 = 2774 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME, TEST_PACKAGE, wifiConfig2, false, 2775 null, false); 2776 2777 WifiConfigManager.OnNetworkUpdateListener listener = mNetworkListenerCaptor.getValue(); 2778 reset(mWifiConfigManager); 2779 2780 // Set user connect choice on this passpoint network 2781 listener.onConnectChoiceSet(Collections.singletonList(wifiConfig), USER_CONNECT_CHOICE, 2782 TEST_RSSI); 2783 verify(provider).setUserConnectChoice(USER_CONNECT_CHOICE, TEST_RSSI); 2784 2785 // The user connect choice is this psspoint network, its user connect choice should null 2786 listener.onConnectChoiceSet(Collections.emptyList(), wifiConfig.getPasspointUniqueId(), 2787 TEST_RSSI); 2788 verify(provider).setUserConnectChoice(null, 0); 2789 2790 // Remove the user connect choice, if equals, user connect choice should set to null 2791 when(provider.getConnectChoice()).thenReturn(USER_CONNECT_CHOICE); 2792 listener.onConnectChoiceRemoved(USER_CONNECT_CHOICE); 2793 verify(provider, times(2)).setUserConnectChoice(null, 0); 2794 2795 verify(provider2, never()).setUserConnectChoice(any(), anyInt()); 2796 verify(mWifiConfigManager, times(3)).saveToStore(true); 2797 } 2798 2799 /* 2800 * Verify that Passpoint manager returns the correct venue URL. 2801 * 2802 * @throws Exception 2803 */ 2804 @Test testGetVenueUrl()2805 public void testGetVenueUrl() throws Exception { 2806 // static mocking 2807 MockitoSession session = 2808 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2809 InformationElementUtil.class).startMocking(); 2810 try { 2811 ScanResult scanResult = createTestScanResult(); 2812 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2813 vsa.anqpDomainID = scanResult.anqpDomainId; 2814 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2815 2816 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 2817 anqpElementMap.put(ANQPElementType.ANQPDomName, 2818 new DomainNameElement(Arrays.asList(new String[]{"test.com"}))); 2819 List<I18Name> names = new ArrayList<>(); 2820 names.add(new I18Name(TEST_LOCALE_ENGLISH, 2821 new Locale.Builder().setLanguage(TEST_LOCALE_ENGLISH).build(), 2822 "Passpoint Venue")); 2823 names.add(new I18Name(TEST_LOCALE_HEBREW, 2824 new Locale.Builder().setLanguage(TEST_LOCALE_HEBREW).build(), "רשת פאספוינט")); 2825 anqpElementMap.put(ANQPElementType.ANQPVenueName, new VenueNameElement(names)); 2826 2827 Map<Integer, URL> venueUrls = new HashMap<>(); 2828 venueUrls.put(1, new URL(TEST_VENUE_URL_ENG)); 2829 venueUrls.put(2, new URL(TEST_VENUE_URL_HEB)); 2830 anqpElementMap.put(ANQPElementType.ANQPVenueUrl, new VenueUrlElement(venueUrls)); 2831 2832 mAnqpCache.addOrUpdateEntry(TEST_ANQP_KEY, anqpElementMap); 2833 ANQPData entry = new ANQPData(mClock, anqpElementMap); 2834 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2835 2836 // Test language 1 2837 Locale.setDefault(new Locale(TEST_LOCALE_ENGLISH)); 2838 URL venueUrl = mManager.getVenueUrl(scanResult); 2839 assertEquals(venueUrl.toString(), TEST_VENUE_URL_ENG); 2840 2841 // Test language 2 2842 Locale.setDefault(new Locale(TEST_LOCALE_HEBREW)); 2843 venueUrl = mManager.getVenueUrl(scanResult); 2844 assertEquals(venueUrl.toString(), TEST_VENUE_URL_HEB); 2845 2846 // Test default language when no language match 2847 Locale.setDefault(new Locale(TEST_LOCALE_SPANISH)); 2848 venueUrl = mManager.getVenueUrl(scanResult); 2849 assertEquals(venueUrl.toString(), TEST_VENUE_URL_ENG); 2850 } finally { 2851 session.finishMocking(); 2852 } 2853 } 2854 2855 /** 2856 * Verify that Passpoint manager returns null when no ANQP entry is available. 2857 * 2858 * @throws Exception 2859 */ 2860 @Test testGetVenueUrlNoAnqpEntry()2861 public void testGetVenueUrlNoAnqpEntry() throws Exception { 2862 // static mocking 2863 MockitoSession session = 2864 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2865 InformationElementUtil.class).startMocking(); 2866 try { 2867 ScanResult scanResult = createTestScanResult(); 2868 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2869 vsa.anqpDomainID = scanResult.anqpDomainId; 2870 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2871 2872 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); 2873 2874 URL venueUrl = mManager.getVenueUrl(scanResult); 2875 assertNull(venueUrl); 2876 } finally { 2877 session.finishMocking(); 2878 } 2879 } 2880 2881 /** 2882 * Verify that Passpoint manager returns null when no Venue URL ANQP-element is available. 2883 * 2884 * @throws Exception 2885 */ 2886 @Test testGetVenueUrlNoVenueUrlAnqpElement()2887 public void testGetVenueUrlNoVenueUrlAnqpElement() throws Exception { 2888 // static mocking 2889 MockitoSession session = 2890 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2891 InformationElementUtil.class).startMocking(); 2892 try { 2893 ScanResult scanResult = createTestScanResult(); 2894 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2895 vsa.anqpDomainID = scanResult.anqpDomainId; 2896 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2897 2898 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 2899 anqpElementMap.put(ANQPElementType.ANQPDomName, 2900 new DomainNameElement(Arrays.asList(new String[]{"test.com"}))); 2901 List<I18Name> names = new ArrayList<>(); 2902 names.add(new I18Name(TEST_LOCALE_ENGLISH, 2903 new Locale.Builder().setLanguage(TEST_LOCALE_ENGLISH).build(), 2904 "Passpoint Venue")); 2905 names.add(new I18Name(TEST_LOCALE_HEBREW, 2906 new Locale.Builder().setLanguage(TEST_LOCALE_HEBREW).build(), "רשת פאספוינט")); 2907 anqpElementMap.put(ANQPElementType.ANQPVenueName, new VenueNameElement(names)); 2908 2909 mAnqpCache.addOrUpdateEntry(TEST_ANQP_KEY, anqpElementMap); 2910 ANQPData entry = new ANQPData(mClock, anqpElementMap); 2911 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2912 2913 URL venueUrl = mManager.getVenueUrl(scanResult); 2914 assertNull(venueUrl); 2915 } finally { 2916 session.finishMocking(); 2917 } 2918 } 2919 2920 /** 2921 * Verify that Passpoint manager returns null when no Venue Name ANQP-element is available. 2922 * 2923 * @throws Exception 2924 */ 2925 @Test testGetVenueUrlNoVenueNameAnqpElement()2926 public void testGetVenueUrlNoVenueNameAnqpElement() throws Exception { 2927 // static mocking 2928 MockitoSession session = 2929 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic( 2930 InformationElementUtil.class).startMocking(); 2931 try { 2932 ScanResult scanResult = createTestScanResult(); 2933 InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 2934 vsa.anqpDomainID = scanResult.anqpDomainId; 2935 when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa); 2936 2937 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 2938 anqpElementMap.put(ANQPElementType.ANQPDomName, 2939 new DomainNameElement(Arrays.asList(new String[]{"test.com"}))); 2940 2941 Map<Integer, URL> venueUrls = new HashMap<>(); 2942 venueUrls.put(1, new URL(TEST_VENUE_URL_ENG)); 2943 venueUrls.put(2, new URL(TEST_VENUE_URL_HEB)); 2944 anqpElementMap.put(ANQPElementType.ANQPVenueUrl, new VenueUrlElement(venueUrls)); 2945 2946 mAnqpCache.addOrUpdateEntry(TEST_ANQP_KEY, anqpElementMap); 2947 ANQPData entry = new ANQPData(mClock, anqpElementMap); 2948 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2949 2950 URL venueUrl = mManager.getVenueUrl(scanResult); 2951 assertNull(venueUrl); 2952 2953 // Now try with an incomplete list of venue names 2954 List<I18Name> names = new ArrayList<>(); 2955 names.add(new I18Name(TEST_LOCALE_ENGLISH, 2956 new Locale.Builder().setLanguage(TEST_LOCALE_ENGLISH).build(), 2957 "Passpoint Venue")); 2958 anqpElementMap.put(ANQPElementType.ANQPVenueName, new VenueNameElement(names)); 2959 entry = new ANQPData(mClock, anqpElementMap); 2960 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 2961 2962 venueUrl = mManager.getVenueUrl(scanResult); 2963 assertNull(venueUrl); 2964 } finally { 2965 session.finishMocking(); 2966 } 2967 } 2968 2969 /** 2970 * Verify that Passpoint manager handles the terms and conditions URL correctly: Accepts only 2971 * HTTPS URLs, and rejects HTTP and invalid URLs. 2972 * 2973 * @throws Exception 2974 */ 2975 @Test testHandleTermsAndConditionsEvent()2976 public void testHandleTermsAndConditionsEvent() throws Exception { 2977 WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork(); 2978 PasspointProvider passpointProvider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 2979 TEST_PACKAGE, config, false, null, false); 2980 assertEquals(TEST_TERMS_AND_CONDITIONS_URL, mManager.handleTermsAndConditionsEvent( 2981 WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 2982 TEST_TERMS_AND_CONDITIONS_URL), config).toString()); 2983 2984 // Verify that this provider is never blocked 2985 verify(passpointProvider, never()).blockBssOrEss(anyLong(), anyBoolean(), anyInt()); 2986 2987 assertNull(mManager.handleTermsAndConditionsEvent( 2988 WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 2989 TEST_TERMS_AND_CONDITIONS_URL_NON_HTTPS), config)); 2990 2991 // Verify that the ESS is blocked for 24 hours, the URL is non-HTTPS and unlikely to change 2992 verify(passpointProvider).blockBssOrEss(eq(TEST_BSSID), eq(true), eq(24 * 60 * 60)); 2993 2994 assertNull(mManager.handleTermsAndConditionsEvent( 2995 WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 2996 TEST_TERMS_AND_CONDITIONS_URL_INVALID), config)); 2997 2998 // Verify that the ESS is blocked for an hour due to a temporary issue with the URL 2999 verify(passpointProvider).blockBssOrEss(eq(TEST_BSSID), eq(true), eq(60 * 60)); 3000 3001 // Now try with a non-Passpoint network 3002 config = WifiConfigurationTestUtil.createEapNetwork(); 3003 assertNull(mManager.handleTermsAndConditionsEvent( 3004 WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 3005 TEST_TERMS_AND_CONDITIONS_URL), config)); 3006 // and a null configuration 3007 assertNull(mManager.handleTermsAndConditionsEvent( 3008 WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 3009 TEST_TERMS_AND_CONDITIONS_URL), null)); 3010 } 3011 3012 /** 3013 * Verify that Passpoint manager clears states and flushes caches as expected. 3014 * 3015 * @throws Exception 3016 */ 3017 @Test testClearAnqpRequestsAndFlushCache()3018 public void testClearAnqpRequestsAndFlushCache() throws Exception { 3019 PasspointProvider provider = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, 3020 TEST_PACKAGE, false, TEST_REALM, false); 3021 3022 mManager.clearAnqpRequestsAndFlushCache(); 3023 verify(mAnqpRequestManager).clear(); 3024 verify(mAnqpCache).flush(); 3025 verify(provider).clearProviderBlock(); 3026 } 3027 3028 /** 3029 * Verify that when Passpoint manager is enabled/disabled the WifiSettingsStore is updated 3030 * with correct value. 3031 * 3032 * @throws Exception 3033 */ 3034 @Test testPasspointEnableSettingsStore()3035 public void testPasspointEnableSettingsStore() throws Exception { 3036 // Disable the Wifi Passpoint, check return value and verify status. 3037 mManager.setWifiPasspointEnabled(false); 3038 assertFalse(mManager.isWifiPasspointEnabled()); 3039 // Verify WifiSettingStore has been called to set Wifi Passpoint status. 3040 verify(mWifiSettingsStore).handleWifiPasspointEnabled(false); 3041 assertFalse(mConfigSettingsPasspointEnabled); 3042 3043 // Enable the Wifi Passpoint, check return value and verify status. 3044 mManager.setWifiPasspointEnabled(true); 3045 assertTrue(mManager.isWifiPasspointEnabled()); 3046 // Verify WifiSettingStore has been called to set Wifi Passpoint status. 3047 verify(mWifiSettingsStore).handleWifiPasspointEnabled(true); 3048 assertTrue(mConfigSettingsPasspointEnabled); 3049 } 3050 3051 /** 3052 * Verify that Passpoint manager is enabled and disabled. 3053 * 3054 * @throws Exception 3055 */ 3056 @Test testPasspointEnableDisable()3057 public void testPasspointEnableDisable() throws Exception { 3058 PasspointProvider provider = 3059 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null, false); 3060 ANQPData entry = new ANQPData(mClock, null); 3061 3062 when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); 3063 when(provider.match(anyMap(), any(RoamingConsortium.class), any(ScanResult.class))) 3064 .thenReturn(PasspointMatch.HomeProvider); 3065 3066 // Disable the Wifi Passpoint and expect the matchProvider to return empty list. 3067 mManager.setWifiPasspointEnabled(false); 3068 assertFalse(mManager.isWifiPasspointEnabled()); 3069 assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty()); 3070 3071 // Enable the Wifi Passpoint and expect the matchProvider to return matched result. 3072 mManager.setWifiPasspointEnabled(true); 3073 assertTrue(mManager.isWifiPasspointEnabled()); 3074 List<Pair<PasspointProvider, PasspointMatch>> results = 3075 mManager.matchProvider(createTestScanResult()); 3076 Pair<PasspointProvider, PasspointMatch> result = results.get(0); 3077 assertEquals(PasspointMatch.HomeProvider, result.second); 3078 assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); 3079 } 3080 } 3081 3082