blob: dbc38d4931cd7064a2cefdacef75d44faf869a2b [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi.hotspot2;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OPSTR_CHANGE_WIFI_STATE;
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_EAP;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.anyMap;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.EAPConstants;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Pair;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.ClientModeImpl;
import com.android.server.wifi.Clock;
import com.android.server.wifi.FakeKeys;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.NetworkUpdateResult;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiCarrierInfoManager;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiConfigurationTestUtil;
import com.android.server.wifi.WifiContext;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiNetworkSuggestionsManager;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
import com.android.server.wifi.hotspot2.anqp.I18Name;
import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
import com.android.server.wifi.util.InformationElementUtil;
import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoSession;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* Unit tests for {@link PasspointManager}.
*/
@SmallTest
public class PasspointManagerTest extends WifiBaseTest {
private static final long BSSID = 0x112233445566L;
private static final String TEST_PACKAGE = "com.android.test";
private static final String TEST_PACKAGE1 = "com.android.test1";
private static final String TEST_FQDN = "test1.test.com";
private static final String TEST_FQDN2 = "test2.test.com";
private static final String TEST_FRIENDLY_NAME = "friendly name";
private static final String TEST_FRIENDLY_NAME2 = "second friendly name";
private static final String TEST_REALM = "realm.test.com";
private static final String TEST_REALM2 = "realm.test2.com";
private static final String TEST_REALM3 = "realm.test3.com";
private static final String TEST_IMSI = "123456*";
private static final String FULL_IMSI = "123456789123456";
private static final int TEST_CARRIER_ID = 10;
private static final int TEST_SUBID = 1;
private static final long TEST_BSSID = 0x112233445566L;
private static final String TEST_SSID = "TestSSID";
private static final String TEST_BSSID_STRING = "11:22:33:44:55:66";
private static final String TEST_SSID2 = "TestSSID2";
private static final String TEST_BSSID_STRING2 = "11:22:33:44:55:77";
private static final String TEST_SSID3 = "TestSSID3";
private static final String TEST_BSSID_STRING3 = "11:22:33:44:55:88";
private static final String TEST_MCC_MNC = "123456";
private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org",
TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3));
private static final long TEST_HESSID = 0x5678L;
private static final int TEST_ANQP_DOMAIN_ID = 0;
private static final int TEST_ANQP_DOMAIN_ID2 = 1;
private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey(
TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID);
private static final ANQPNetworkKey TEST_ANQP_KEY2 = ANQPNetworkKey.buildKey(
TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID2);
private static final int TEST_CREATOR_UID = 1234;
private static final int TEST_CREATOR_UID1 = 1235;
private static final int TEST_UID = 1500;
private static final int TEST_NETWORK_ID = 2;
@Mock Context mContext;
@Mock WifiNative mWifiNative;
@Mock WifiKeyStore mWifiKeyStore;
@Mock Clock mClock;
@Mock PasspointObjectFactory mObjectFactory;
@Mock PasspointEventHandler.Callbacks mCallbacks;
@Mock AnqpCache mAnqpCache;
@Mock ANQPRequestManager mAnqpRequestManager;
@Mock WifiConfigManager mWifiConfigManager;
@Mock WifiConfigStore mWifiConfigStore;
PasspointConfigSharedStoreData.DataSource mSharedDataSource;
PasspointConfigUserStoreData.DataSource mUserDataSource;
@Mock WifiMetrics mWifiMetrics;
@Mock OsuNetworkConnection mOsuNetworkConnection;
@Mock OsuServerConnection mOsuServerConnection;
@Mock PasspointProvisioner mPasspointProvisioner;
@Mock IProvisioningCallback mCallback;
@Mock WfaKeyStore mWfaKeyStore;
@Mock KeyStore mKeyStore;
@Mock AppOpsManager mAppOpsManager;
@Mock WifiInjector mWifiInjector;
@Mock ClientModeImpl mClientModeImpl;
@Mock TelephonyManager mTelephonyManager;
@Mock SubscriptionManager mSubscriptionManager;
@Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
Handler mHandler;
TestLooper mLooper;
PasspointManager mManager;
ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor =
ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class);
WifiCarrierInfoManager mWifiCarrierInfoManager;
/** Sets up test. */
@Before
public void setUp() throws Exception {
initMocks(this);
when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache);
when(mObjectFactory.makeANQPRequestManager(any(), eq(mClock)))
.thenReturn(mAnqpRequestManager);
when(mObjectFactory.makeOsuNetworkConnection(any(Context.class)))
.thenReturn(mOsuNetworkConnection);
when(mObjectFactory.makeOsuServerConnection())
.thenReturn(mOsuServerConnection);
when(mObjectFactory.makeWfaKeyStore()).thenReturn(mWfaKeyStore);
when(mWfaKeyStore.get()).thenReturn(mKeyStore);
when(mObjectFactory.makePasspointProvisioner(any(Context.class), any(WifiNative.class),
any(PasspointManager.class), any(WifiMetrics.class)))
.thenReturn(mPasspointProvisioner);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
when(mWifiInjector.getWifiNetworkSuggestionsManager())
.thenReturn(mWifiNetworkSuggestionsManager);
mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager,
mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class),
mock(WifiContext.class), mWifiConfigStore, mock(Handler.class), mWifiMetrics);
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager,
mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager);
ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks =
ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class);
verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class),
callbacks.capture());
ArgumentCaptor<PasspointConfigSharedStoreData.DataSource> sharedDataSource =
ArgumentCaptor.forClass(PasspointConfigSharedStoreData.DataSource.class);
verify(mObjectFactory).makePasspointConfigSharedStoreData(sharedDataSource.capture());
ArgumentCaptor<PasspointConfigUserStoreData.DataSource> userDataSource =
ArgumentCaptor.forClass(PasspointConfigUserStoreData.DataSource.class);
verify(mObjectFactory).makePasspointConfigUserStoreData(any(WifiKeyStore.class),
any(WifiCarrierInfoManager.class), userDataSource.capture());
mCallbacks = callbacks.getValue();
mSharedDataSource = sharedDataSource.getValue();
mUserDataSource = userDataSource.getValue();
// SIM is absent
when(mSubscriptionManager.getActiveSubscriptionInfoList())
.thenReturn(Collections.emptyList());
}
/**
* Verify that the given Passpoint configuration matches the one that's added to
* the PasspointManager.
*
* @param expectedConfig The expected installed Passpoint configuration
*/
private void verifyInstalledConfig(PasspointConfiguration expectedConfig) {
List<PasspointConfiguration> installedConfigs =
mManager.getProviderConfigs(TEST_CREATOR_UID, true);
assertEquals(1, installedConfigs.size());
assertEquals(expectedConfig, installedConfigs.get(0));
}
private PasspointProvider createMockProvider(PasspointConfiguration config) {
WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1,
TEST_UID, "\"PasspointTestSSID\"", true, true,
config.getHomeSp().getFqdn(), TEST_FRIENDLY_NAME, SECURITY_EAP);
return createMockProvider(config, wifiConfig, false);
}
/**
* Create a mock PasspointProvider with default expectations.
*
* @param config The configuration associated with the provider
* @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
*/
private PasspointProvider createMockProvider(
PasspointConfiguration config, WifiConfiguration wifiConfig, boolean isSuggestion) {
PasspointProvider provider = mock(PasspointProvider.class);
when(provider.installCertsAndKeys()).thenReturn(true);
lenient().when(provider.getConfig()).thenReturn(config);
lenient().when(provider.getWifiConfig()).thenReturn(wifiConfig);
lenient().when(provider.getCreatorUid()).thenReturn(TEST_CREATOR_UID);
lenient().when(provider.isFromSuggestion()).thenReturn(isSuggestion);
lenient().when(provider.isAutojoinEnabled()).thenReturn(true);
return provider;
}
/**
* Helper function for creating a test configuration with user credential.
*
* @return {@link PasspointConfiguration}
*/
private PasspointConfiguration createTestConfigWithUserCredential(String fqdn,
String friendlyName) {
return createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, TEST_REALM);
}
/**
* Helper function for creating a test configuration with user credential
* and a unique realm.
*
* @return {@link PasspointConfiguration}
*/
private PasspointConfiguration createTestConfigWithUserCredentialAndRealm(String fqdn,
String friendlyName, String realm) {
PasspointConfiguration config = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
config.setHomeSp(homeSp);
Map<String, String> friendlyNames = new HashMap<>();
friendlyNames.put("en", friendlyName);
friendlyNames.put("kr", friendlyName + 1);
friendlyNames.put("jp", friendlyName + 2);
config.setServiceFriendlyNames(friendlyNames);
Credential credential = new Credential();
credential.setRealm(realm != null ? realm : TEST_REALM);
credential.setCaCertificate(FakeKeys.CA_CERT0);
Credential.UserCredential userCredential = new Credential.UserCredential();
userCredential.setUsername("username");
userCredential.setPassword("password");
userCredential.setEapType(EAPConstants.EAP_TTLS);
userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAP);
credential.setUserCredential(userCredential);
config.setCredential(credential);
return config;
}
/**
* Helper function for creating a test configuration with SIM credential.
*
* @return {@link PasspointConfiguration}
*/
private PasspointConfiguration createTestConfigWithSimCredential(String fqdn, String imsi,
String realm) {
PasspointConfiguration config = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
config.setHomeSp(homeSp);
Credential credential = new Credential();
credential.setRealm(TEST_REALM);
Credential.SimCredential simCredential = new Credential.SimCredential();
simCredential.setImsi(imsi);
simCredential.setEapType(EAPConstants.EAP_SIM);
credential.setSimCredential(simCredential);
config.setCredential(credential);
return config;
}
private PasspointProvider addTestProvider(String fqdn, String friendlyName,
String packageName, boolean isSuggestion, String realm) {
WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1, TEST_UID,
"\"PasspointTestSSID\"", true, true,
fqdn, friendlyName, SECURITY_EAP);
return addTestProvider(fqdn, friendlyName, packageName, wifiConfig, isSuggestion, realm);
}
/**
* Helper function for adding a test provider to the manager. Return the mock
* provider that's added to the manager.
*
* @return {@link PasspointProvider}
*/
private PasspointProvider addTestProvider(String fqdn, String friendlyName,
String packageName, WifiConfiguration wifiConfig, boolean isSuggestion, String realm) {
PasspointConfiguration config =
createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, realm);
wifiConfig.setPasspointUniqueId(config.getUniqueId());
PasspointProvider provider = createMockProvider(config, wifiConfig, isSuggestion);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(isSuggestion))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(packageName);
assertTrue(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, isSuggestion, true));
return provider;
}
/**
* Helper function for creating a ScanResult for testing.
*
* @return {@link ScanResult}
*/
private ScanResult createTestScanResult() {
ScanResult scanResult = new ScanResult();
scanResult.SSID = TEST_SSID;
scanResult.BSSID = TEST_BSSID_STRING;
scanResult.hessid = TEST_HESSID;
scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID;
scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
return scanResult;
}
/**
* Helper function for creating a ScanResult for testing.
*
* @return {@link ScanResult}
*/
private List<ScanResult> createTestScanResults() {
List<ScanResult> scanResults = new ArrayList<>();
// Passpoint AP
ScanResult scanResult = new ScanResult();
scanResult.SSID = TEST_SSID;
scanResult.BSSID = TEST_BSSID_STRING;
scanResult.hessid = TEST_HESSID;
scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID2;
scanResults.add(scanResult);
// Non-Passpoint AP
ScanResult scanResult2 = new ScanResult();
scanResult2.SSID = TEST_SSID2;
scanResult2.BSSID = TEST_BSSID_STRING2;
scanResult2.hessid = TEST_HESSID;
scanResult2.flags = 0;
scanResults.add(scanResult2);
// Passpoint AP
ScanResult scanResult3 = new ScanResult();
scanResult3.SSID = TEST_SSID3;
scanResult3.BSSID = TEST_BSSID_STRING3;
scanResult3.hessid = TEST_HESSID;
scanResult3.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
scanResult3.anqpDomainId = TEST_ANQP_DOMAIN_ID2;
scanResults.add(scanResult3);
return scanResults;
}
/**
* Verify that the ANQP elements will be added to the ANQP cache on receiving a successful
* response.
*
* @throws Exception
*/
@Test
public void anqpResponseSuccess() throws Exception {
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY);
mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
verify(mAnqpCache).addEntry(TEST_ANQP_KEY, anqpElementMap);
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
any(String.class));
}
/**
* Verify that no ANQP elements will be added to the ANQP cache on receiving a successful
* response for a request that's not sent by us.
*
* @throws Exception
*/
@Test
public void anqpResponseSuccessWithUnknownRequest() throws Exception {
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null);
mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
}
/**
* Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response.
*
* @throws Exception
*/
@Test
public void anqpResponseFailure() throws Exception {
when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY);
mCallbacks.onANQPResponse(TEST_BSSID, null);
verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
}
/**
* Verify that adding a provider with a null configuration will fail.
*
* @throws Exception
*/
@Test
public void addProviderWithNullConfig() throws Exception {
assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a provider with a empty configuration will fail.
*
* @throws Exception
*/
@Test
public void addProviderWithEmptyConfig() throws Exception {
assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID,
TEST_PACKAGE, false, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify taht adding a provider with an invalid credential will fail (using EAP-TLS
* for user credential).
*
* @throws Exception
*/
@Test
public void addProviderWithInvalidCredential() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
// EAP-TLS not allowed for user credential.
config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS);
assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a user saved provider with a valid configuration and user credential will
* succeed.
*
* @throws Exception
*/
private void addRemoveSavedProviderWithValidUserCredential(boolean useFqdn) throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(config);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE),
any(AppOpsManager.OnOpChangedListener.class));
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify content in the data source.
List<PasspointProvider> providers = mUserDataSource.getProviders();
assertEquals(1, providers.size());
assertEquals(config, providers.get(0).getConfig());
// Verify calling |enableAutoJoin|, |enableMacRandomization|, and |setMeteredOverride|
verifyEnableAutojoin(providers.get(0), useFqdn);
verifyEnableMacRandomization(providers.get(0));
verifySetMeteredOverride(providers.get(0));
// Provider index start with 0, should be 1 after adding a provider.
assertEquals(1, mSharedDataSource.getProviderIndex());
// Remove the provider as the creator app.
if (useFqdn) {
assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
} else {
assertTrue(
mManager.removeProvider(TEST_CREATOR_UID, false, config.getUniqueId(), null));
}
verify(provider).uninstallCertsAndKeys();
verify(mWifiConfigManager, times(3)).removePasspointConfiguredNetwork(
provider.getWifiConfig().getKey());
/**
* 1 from |removeProvider| + 2 from |setAutojoinEnabled| + 2 from
* |enableMacRandomization| + 2 from |setMeteredOverride| = 7 calls to |saveToStore|
*/
verify(mWifiConfigManager, times(7)).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class));
assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
// Verify content in the data source.
assertTrue(mUserDataSource.getProviders().isEmpty());
// Removing a provider should not change the provider index.
assertEquals(1, mSharedDataSource.getProviderIndex());
}
/**
* Verify that adding a user saved provider with a valid configuration and user credential will
* succeed. Remove provider using FQDN as key.
*
* @throws Exception
*/
@Test
public void addRemoveByFqdnSavedProviderWithValidUserCredential() throws Exception {
addRemoveSavedProviderWithValidUserCredential(true);
}
/**
* Verify that adding a user saved provider with a valid configuration and user credential will
* succeed. Remove provider using unique identifier as key.
*
* @throws Exception
*/
@Test
public void addRemoveByUniqueIdSavedProviderWithValidUserCredential() throws Exception {
addRemoveSavedProviderWithValidUserCredential(false);
}
/**
* Verify enable/disable autojoin on a provider.
* @param provider a mock provider that is already added into the PasspointManager
*/
private void verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn) {
when(provider.setAutojoinEnabled(anyBoolean())).thenReturn(true);
if (useFqdn) {
assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(),
false));
verify(provider).setAutojoinEnabled(false);
assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(),
true));
verify(provider).setAutojoinEnabled(true);
assertFalse(mManager.enableAutojoin(null, provider.getConfig().getHomeSp()
.getFqdn() + "-XXXX", true));
} else {
assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null,
false));
verify(provider).setAutojoinEnabled(false);
assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null,
true));
verify(provider).setAutojoinEnabled(true);
assertFalse(
mManager.enableAutojoin(provider.getConfig().getHomeSp().getFqdn() + "-XXXX",
null, true));
}
verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF,
false, true);
verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON,
false, true);
}
/**
* Verify enable/disable mac randomization on a provider.
* @param provider a mock provider that is already added into the PasspointManager
*/
private void verifyEnableMacRandomization(PasspointProvider provider) {
when(provider.setMacRandomizationEnabled(anyBoolean())).thenReturn(true);
assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
false));
verify(provider).setMacRandomizationEnabled(false);
verify(mWifiMetrics).logUserActionEvent(
UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF, false, true);
assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
true));
verify(mWifiConfigManager, times(2)).removePasspointConfiguredNetwork(
provider.getWifiConfig().getKey());
verify(mWifiMetrics).logUserActionEvent(
UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON, false, true);
verify(provider).setMacRandomizationEnabled(true);
assertFalse(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn()
+ "-XXXX", false));
}
private void verifySetMeteredOverride(PasspointProvider provider) {
when(provider.setMeteredOverride(anyInt())).thenReturn(true);
assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
METERED_OVERRIDE_METERED));
verify(provider).setMeteredOverride(METERED_OVERRIDE_METERED);
verify(mWifiMetrics).logUserActionEvent(
UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED, false, true);
assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
METERED_OVERRIDE_NOT_METERED));
verify(provider).setMeteredOverride(METERED_OVERRIDE_NOT_METERED);
verify(mWifiMetrics).logUserActionEvent(
UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED, false, true);
assertFalse(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn()
+ "-XXXX", METERED_OVERRIDE_METERED));
}
/**
* Verify that adding a user saved provider with a valid configuration and SIM credential will
* succeed.
*
* @throws Exception
*/
@Test
public void addRemoveSavedProviderWithValidSimCredential() throws Exception {
PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(config);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify content in the data source.
List<PasspointProvider> providers = mUserDataSource.getProviders();
assertEquals(1, providers.size());
assertEquals(config, providers.get(0).getConfig());
// Provider index start with 0, should be 1 after adding a provider.
assertEquals(1, mSharedDataSource.getProviderIndex());
// Remove the provider as a privileged non-creator app.
assertTrue(mManager.removeProvider(TEST_UID, true, null, TEST_FQDN));
verify(provider).uninstallCertsAndKeys();
verify(mWifiConfigManager).removePasspointConfiguredNetwork(
provider.getWifiConfig().getKey());
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
assertTrue(mManager.getProviderConfigs(TEST_UID, true).isEmpty());
// Verify content in the data source.
assertTrue(mUserDataSource.getProviders().isEmpty());
// Removing a provider should not change the provider index.
assertEquals(1, mSharedDataSource.getProviderIndex());
}
/**
* Verify that if the passpoint profile has full IMSI, the carrier ID should be updated when
* the matched SIM card is present.
* @throws Exception
*/
@Test
public void addProviderWithValidFullImsiOfSimCredential() throws Exception {
PasspointConfiguration config =
createTestConfigWithSimCredential(TEST_FQDN, FULL_IMSI, TEST_REALM);
X509Certificate[] certArr = new X509Certificate[] {FakeKeys.CA_CERT0};
config.getCredential().setCaCertificates(certArr);
SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
when(subInfo.getSubscriptionId()).thenReturn(TEST_SUBID);
when(subInfo.getCarrierId()).thenReturn(TEST_CARRIER_ID);
TelephonyManager specifiedTm = mock(TelephonyManager.class);
when(mTelephonyManager.createForSubscriptionId(eq(TEST_SUBID))).thenReturn(specifiedTm);
when(specifiedTm.getSubscriberId()).thenReturn(FULL_IMSI);
List<SubscriptionInfo> subInfoList = new ArrayList<SubscriptionInfo>() {{
add(subInfo);
}};
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfoList);
when(mWifiKeyStore.putCaCertInKeyStore(any(String.class), any(Certificate.class)))
.thenReturn(true);
PasspointObjectFactory spyFactory = spy(new PasspointObjectFactory());
when(mWifiNetworkSuggestionsManager.isPasspointSuggestionSharedWithUser(any()))
.thenReturn(true);
PasspointManager ut = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
mWifiKeyStore, mClock, spyFactory, mWifiConfigManager,
mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager);
assertTrue(ut.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
assertEquals(TEST_CARRIER_ID, config.getCarrierId());
List<String> passpointProfilesList = new ArrayList<String>(){{
add(config.getUniqueId());
}};
assertEquals(TEST_CARRIER_ID,
ut.getWifiConfigsForPasspointProfiles(passpointProfilesList).get(0).carrierId);
}
/**
* Verify that adding a user saved provider with the same base domain as the existing provider
* will succeed, and verify that the new provider with the new configuration is added.
*
* @throws Exception
*/
@Test
public void addSavedProviderWithExistingConfig() throws Exception {
// Add a provider with the original configuration.
PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(origConfig);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify data source content.
List<PasspointProvider> origProviders = mUserDataSource.getProviders();
assertEquals(1, origProviders.size());
assertEquals(origConfig, origProviders.get(0).getConfig());
assertEquals(1, mSharedDataSource.getProviderIndex());
// Add same provider as existing suggestion provider
// This should be no WifiConfig deletion
WifiConfiguration origWifiConfig = origProvider.getWifiConfig();
when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getKey()))
.thenReturn(origWifiConfig);
when(mWifiConfigManager.addOrUpdateNetwork(
origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
origWifiConfig.getKey());
verify(mWifiConfigManager).addOrUpdateNetwork(
argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE));
verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
assertEquals(2, mSharedDataSource.getProviderIndex());
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Add another provider with the same base domain as the existing provider.
// This should replace the existing provider with the new configuration.
PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(newProvider);
when(mWifiConfigManager.getConfiguredNetwork(origProvider.getWifiConfig().getKey()))
.thenReturn(origWifiConfig);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
List<PasspointConfiguration> installedConfigs =
mManager.getProviderConfigs(TEST_CREATOR_UID, true);
assertEquals(2, installedConfigs.size());
assertTrue(installedConfigs.contains(origConfig));
assertTrue(installedConfigs.contains(newConfig));
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
// Verify data source content.
List<PasspointProvider> newProviders = mUserDataSource.getProviders();
assertEquals(2, newProviders.size());
assertTrue(newConfig.equals(newProviders.get(0).getConfig())
|| newConfig.equals(newProviders.get(1).getConfig()));
assertEquals(3, mSharedDataSource.getProviderIndex());
}
/**
* Verify that adding a provider will fail when failing to install certificates and
* key to the keystore.
*
* @throws Exception
*/
@Test
public void addProviderOnKeyInstallationFailiure() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = mock(PasspointProvider.class);
when(provider.installCertsAndKeys()).thenReturn(false);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), eq(
mWifiCarrierInfoManager),
anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a provider with R1 configuration and a private self-signed CA certificate
* is installed correctly.
*
* @throws Exception
*/
@Test
public void addProviderWithR1ConfigPrivateCaCert() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(config);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a provider with R2 configuration will not perform CA certificate
* verification.
*
* @throws Exception
*/
@Test
public void addProviderWithR2Config() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
config.setUpdateIdentifier(1);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(config);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that removing a non-existing provider will fail.
*
* @throws Exception
*/
@Test
public void removeNonExistingProvider() throws Exception {
assertFalse(mManager.removeProvider(TEST_CREATOR_UID, true, null, TEST_FQDN));
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
}
/**
* Verify that a empty list will be returned when no providers are installed.
*
* @throws Exception
*/
@Test
public void matchProviderWithNoProvidersInstalled() throws Exception {
assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
}
/**
* Verify that a {code null} be returned when ANQP entry doesn't exist in the cache.
*
* @throws Exception
*/
@Test
public void matchProviderWithAnqpCacheMissed() throws Exception {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.hsRelease = NetworkDetail.HSRelease.R1;
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
InformationElementUtil.RoamingConsortium roamingConsortium =
new InformationElementUtil.RoamingConsortium();
roamingConsortium.anqpOICount = 0;
when(InformationElementUtil.getRoamingConsortiumIE(isNull()))
.thenReturn(roamingConsortium);
assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
// Verify that a request for ANQP elements is initiated.
verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID),
any(ANQPNetworkKey.class),
anyBoolean(), any(NetworkDetail.HSRelease.class));
} finally {
session.finishMocking();
}
}
/**
* Verify that the expected provider will be returned when a HomeProvider is matched.
*
* @throws Exception
*/
@Test
public void matchProviderAsHomeProvider() throws Exception {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
ANQPData entry = new ANQPData(mClock, null);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(provider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.HomeProvider);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
Pair<PasspointProvider, PasspointMatch> result = results.get(0);
assertEquals(PasspointMatch.HomeProvider, result.second);
assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
}
/**
* Verify that the expected provider will be returned when a RoamingProvider is matched.
*
* @throws Exception
*/
@Test
public void matchProviderAsRoamingProvider() throws Exception {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
ANQPData entry = new ANQPData(mClock, null);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(provider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.RoamingProvider);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
Pair<PasspointProvider, PasspointMatch> result = results.get(0);
assertEquals(PasspointMatch.RoamingProvider, result.second);
assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
}
/**
* When multiple providers matched for a single scanResult, when there is any home provider
* available, return all matched home provider. Otherwise return all roaming provider.
*/
@Test
public void matchScanResultWithMultipleProviderAsHomeAndRoaming() {
// Only add roaming providers.
PasspointProvider roamingProvider1 =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
PasspointProvider roamingProvider2 =
addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE1, false, null);
ANQPData entry = new ANQPData(mClock, null);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(roamingProvider1.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.RoamingProvider);
when(roamingProvider2.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.RoamingProvider);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
// Return all matched roaming providers.
assertEquals(2, results.size());
for (Pair<PasspointProvider, PasspointMatch> result : results) {
assertEquals(PasspointMatch.RoamingProvider, result.second);
}
// Add home providers.
PasspointProvider homeProvider1 =
addTestProvider(TEST_FQDN + "home", TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
PasspointProvider homeProvider2 = addTestProvider(TEST_FQDN2 + "home", TEST_FRIENDLY_NAME2,
TEST_PACKAGE1, false, null);
when(homeProvider1.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.HomeProvider);
when(homeProvider2.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.HomeProvider);
results = mManager.matchProvider(createTestScanResult());
// When home providers are available, should return all home providers.
assertEquals(2, results.size());
for (Pair<PasspointProvider, PasspointMatch> result : results) {
assertEquals(PasspointMatch.HomeProvider, result.second);
}
}
/**
* Verify that a {code null} will be returned when there is no matching provider.
*
* @throws Exception
*/
@Test
public void matchProviderWithNoMatch() throws Exception {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
ANQPData entry = new ANQPData(mClock, null);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(provider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.None);
assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
}
/**
* Verify the expectations for sweepCache.
*
* @throws Exception
*/
@Test
public void sweepCache() throws Exception {
mManager.sweepCache();
verify(mAnqpCache).sweep();
}
/**
* Verify that an empty map will be returned if ANQP elements are not cached for the given AP.
*
* @throws Exception
*/
@Test
public void getANQPElementsWithNoMatchFound() throws Exception {
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty());
}
/**
* Verify that an expected ANQP elements will be returned if ANQP elements are cached for the
* given AP.
*
* @throws Exception
*/
@Test
public void getANQPElementsWithMatchFound() throws Exception {
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
ANQPData entry = new ANQPData(mClock, anqpElementMap);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult()));
}
/**
* Verify that if the Carrier ID is updated during match, the config should be persisted.
*/
@Test
public void getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential() {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
PasspointProvider provider = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
when(provider.tryUpdateCarrierId()).thenReturn(true);
reset(mWifiConfigManager);
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
when(provider.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.HomeProvider);
List<Pair<PasspointProvider, PasspointMatch>> matchedProviders =
mManager.getAllMatchedProviders(createTestScanResult());
verify(mWifiConfigManager).saveToStore(eq(true));
} finally {
session.finishMocking();
}
}
/**
* Verify that an expected map of FQDN and a list of ScanResult will be returned when provided
* scanResults are matched to installed Passpoint profiles.
*/
@Test
public void getAllMatchingFqdnsForScanResults() {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
providerHome.getWifiConfig().isHomeProviderNetwork = true;
PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
TEST_UID, "\"PasspointTestSSID\"", true, true,
TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, wifiConfiguration, false, null);
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
when(providerHome.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.HomeProvider);
when(providerRoaming.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.RoamingProvider);
when(providerNone.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.None);
Map<String, Map<Integer, List<ScanResult>>> configs =
mManager.getAllMatchingPasspointProfilesForScanResults(
createTestScanResults());
// Expects to be matched with home Provider for each AP (two APs).
assertEquals(2, configs.get(providerHome.getConfig().getUniqueId()).get(
WifiManager.PASSPOINT_HOME_NETWORK).size());
assertFalse(configs.get(providerHome.getConfig().getUniqueId())
.containsKey(WifiManager.PASSPOINT_ROAMING_NETWORK));
// Expects to be matched with roaming Provider for each AP (two APs).
assertEquals(2, configs.get(providerRoaming.getConfig().getUniqueId()).get(
WifiManager.PASSPOINT_ROAMING_NETWORK).size());
assertFalse(configs.get(providerRoaming.getConfig().getUniqueId())
.containsKey(WifiManager.PASSPOINT_HOME_NETWORK));
} finally {
session.finishMocking();
}
}
/**
* Verify that an expected list of {@link WifiConfiguration} will be returned when provided
* a list of FQDN is matched to installed Passpoint profiles. For suggestion passpoint network,
* will check if that suggestion share credential with user to choose from wifi picker.
*/
@Test
public void getWifiConfigsForPasspointProfiles() {
PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
PasspointProvider provider2 = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
PasspointProvider provider3 = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
assertEquals(3, mManager.getWifiConfigsForPasspointProfiles(
Arrays.asList(provider1.getConfig().getUniqueId(),
provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
TEST_FQDN + "_353ab8c93", TEST_FQDN + "_83765319aca")).size());
PasspointProvider provider4 = addTestProvider(TEST_FQDN + 3, TEST_FRIENDLY_NAME,
TEST_PACKAGE, true, null);
when(mWifiNetworkSuggestionsManager
.isPasspointSuggestionSharedWithUser(provider4.getWifiConfig())).thenReturn(false);
assertEquals(3, mManager.getWifiConfigsForPasspointProfiles(
Arrays.asList(provider1.getConfig().getUniqueId(),
provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
provider4.getConfig().getUniqueId(), TEST_FQDN + "_83765319aca")).size());
PasspointProvider provider5 = addTestProvider(TEST_FQDN + 4, TEST_FRIENDLY_NAME,
TEST_PACKAGE, true, null);
when(mWifiNetworkSuggestionsManager
.isPasspointSuggestionSharedWithUser(provider5.getWifiConfig())).thenReturn(true);
assertEquals(4, mManager.getWifiConfigsForPasspointProfiles(
Arrays.asList(provider1.getConfig().getUniqueId(),
provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
provider4.getConfig().getUniqueId(), provider5.getConfig().getUniqueId()))
.size());
}
/**
* Verify that an empty map will be returned when trying to get all matching FQDN for a {@code
* null} {@link ScanResult}.
*/
@Test
public void getAllMatchingFqdnsForScanResultsWithNullScanResult() throws Exception {
assertEquals(0,
mManager.getAllMatchingPasspointProfilesForScanResults(null).size());
}
/**
* Verify that an empty map will be returned when trying to get a all matching FQDN for a {@link
* ScanResult} with a {@code null} BSSID.
*/
@Test
public void getAllMatchingFqdnsForScanResultsWithNullBSSID() throws Exception {
ScanResult scanResult = createTestScanResult();
scanResult.BSSID = null;
assertEquals(0,
mManager.getAllMatchingPasspointProfilesForScanResults(
Arrays.asList(scanResult)).size());
}
/**
* Verify that an empty map will be returned when trying to get all matching FQDN for a {@link
* ScanResult} with an invalid BSSID.
*/
@Test
public void ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID() throws Exception {
ScanResult scanResult = createTestScanResult();
scanResult.BSSID = "asdfdasfas";
assertEquals(0,
mManager.getAllMatchingPasspointProfilesForScanResults(
Arrays.asList(scanResult)).size());
}
/**
* Verify that an empty map will be returned when trying to get all matching FQDN for a
* non-Passpoint AP.
*/
@Test
public void getAllMatchingFqdnsForScanResultsForNonPasspointAP() throws Exception {
ScanResult scanResult = createTestScanResult();
scanResult.flags = 0;
assertEquals(0,
mManager.getAllMatchingPasspointProfilesForScanResults(
Arrays.asList(scanResult)).size());
}
/**
* Verify that an empty list will be returned when retrieving OSU providers for an AP with
* null scan result.
*
* @throws Exception
*/
@Test
public void getMatchingOsuProvidersForNullScanResult() throws Exception {
assertTrue(mManager.getMatchingOsuProviders(null).isEmpty());
}
/**
* Verify that an empty list will be returned when retrieving OSU providers for an AP with
* invalid BSSID.
*
* @throws Exception
*/
@Test
public void getMatchingOsuProvidersForInvalidBSSID() throws Exception {
ScanResult scanResult = createTestScanResult();
scanResult.BSSID = "asdfdasfas";
assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty());
}
/**
* Verify that an empty list will be returned when retrieving OSU providers for a
* non-Passpoint AP.
*
* @throws Exception
*/
@Test
public void getMatchingOsuProvidersForNonPasspointAP() throws Exception {
ScanResult scanResult = createTestScanResult();
scanResult.flags = 0;
assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty());
}
/**
* Verify that an empty list will be returned when no match is found from the ANQP cache.
*
* @throws Exception
*/
@Test
public void getMatchingOsuProviderWithNoMatch() throws Exception {
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
assertTrue(
mManager.getMatchingOsuProviders(Arrays.asList(createTestScanResult())).isEmpty());
}
/**
* Verify that an expected provider list will be returned when a match is found from
* the ANQP cache with a given list of scanResult.
*
* @throws Exception
*/
@Test
public void getMatchingOsuProvidersWithMatch() throws Exception {
// Setup OSU providers ANQP element for AP1.
List<OsuProviderInfo> providerInfoListOfAp1 = new ArrayList<>();
Map<ANQPElementType, ANQPElement> anqpElementMapOfAp1 = new HashMap<>();
Set<OsuProvider> expectedOsuProvidersForDomainId = new HashSet<>();
// Setup OSU providers ANQP element for AP2.
List<OsuProviderInfo> providerInfoListOfAp2 = new ArrayList<>();
Map<ANQPElementType, ANQPElement> anqpElementMapOfAp2 = new HashMap<>();
Set<OsuProvider> expectedOsuProvidersForDomainId2 = new HashSet<>();
int osuProviderCount = 4;
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
for (int i = 0; i < osuProviderCount; i++) {
// Test data.
String friendlyName = "Test Provider" + i;
String serviceDescription = "Dummy Service" + i;
Uri serverUri = Uri.parse("https://" + "test" + i + ".com");
String nai = "access.test.com";
List<Integer> methodList = Arrays.asList(1);
List<I18Name> friendlyNames = Arrays.asList(
new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, friendlyName));
List<I18Name> serviceDescriptions = Arrays.asList(
new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH,
serviceDescription));
Map<String, String> friendlyNameMap = new HashMap<>();
friendlyNames.forEach(e -> friendlyNameMap.put(e.getLanguage(), e.getText()));
expectedOsuProvidersForDomainId.add(new OsuProvider(
(WifiSsid) null, friendlyNameMap, serviceDescription,
serverUri, nai, methodList));
// add All OSU Providers for AP1.
providerInfoListOfAp1.add(new OsuProviderInfo(
friendlyNames, serverUri, methodList, null, nai, serviceDescriptions));
// add only half of All OSU Providers for AP2.
if (i >= osuProviderCount / 2) {
providerInfoListOfAp2.add(new OsuProviderInfo(
friendlyNames, serverUri, methodList, null, nai, serviceDescriptions));
expectedOsuProvidersForDomainId2.add(new OsuProvider(
(WifiSsid) null, friendlyNameMap, serviceDescription,
serverUri, nai, methodList));
}
}
anqpElementMapOfAp1.put(ANQPElementType.HSOSUProviders,
new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID"),
providerInfoListOfAp1));
ANQPData anqpData = new ANQPData(mClock, anqpElementMapOfAp1);
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(anqpData);
anqpElementMapOfAp2.put(ANQPElementType.HSOSUProviders,
new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID2"),
providerInfoListOfAp2));
ANQPData anqpData2 = new ANQPData(mClock, anqpElementMapOfAp2);
when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(anqpData2);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
// ANQP_DOMAIN_ID(TEST_ANQP_KEY)
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
assertEquals(mManager.getMatchingOsuProviders(
Arrays.asList(createTestScanResult())).keySet(),
expectedOsuProvidersForDomainId);
// ANQP_DOMAIN_ID2(TEST_ANQP_KEY2)
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
assertEquals(mManager.getMatchingOsuProviders(
createTestScanResults()).keySet(), expectedOsuProvidersForDomainId2);
} finally {
session.finishMocking();
}
}
/**
* Verify that matching Passpoint configurations will be returned as map with corresponding
* OSU providers.
*/
@Test
public void getMatchingPasspointConfigsForOsuProvidersWithMatch() {
PasspointProvider provider1 =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
PasspointProvider provider2 =
addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null);
List<OsuProvider> osuProviders = new ArrayList<>();
Map<String, String> friendlyNames = new HashMap<>();
friendlyNames.put("en", "NO-MATCH-NAME");
friendlyNames.put("kr", TEST_FRIENDLY_NAME + 1);
osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
friendlyNames));
friendlyNames = new HashMap<>();
friendlyNames.put("en", TEST_FRIENDLY_NAME2);
osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
friendlyNames));
Map<OsuProvider, PasspointConfiguration> results =
mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders);
assertEquals(2, results.size());
assertThat(Arrays.asList(provider1.getConfig(), provider2.getConfig()),
containsInAnyOrder(results.values().toArray()));
}
/**
* Verify that empty map will be returned when there is no matching Passpoint configuration.
*/
@Test
public void getMatchingPasspointConfigsForOsuProvidersWitNoMatch() {
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null);
List<OsuProvider> osuProviders = new ArrayList<>();
Map<String, String> friendlyNames = new HashMap<>();
friendlyNames.put("en", "NO-MATCH-NAME");
osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
friendlyNames));
friendlyNames = new HashMap<>();
friendlyNames.put("en", "NO-MATCH-NAME-2");
osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
friendlyNames));
assertEquals(0, mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders).size());
}
/**
* Verify that the provider list maintained by the PasspointManager after the list is updated
* in the data source.
*
* @throws Exception
*/
@Test
public void verifyProvidersAfterDataSourceUpdate() throws Exception {
// Update the provider list in the data source.
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
List<PasspointProvider> providers = new ArrayList<>();
providers.add(provider);
mUserDataSource.setProviders(providers);
// Verify the providers maintained by PasspointManager.
assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size());
assertEquals(config, mManager.getProviderConfigs(TEST_CREATOR_UID, true).get(0));
}
/**
* Verify that the provider index used by PasspointManager is updated after it is updated in
* the data source.
*
* @throws Exception
*/
@Test
public void verifyProviderIndexAfterDataSourceUpdate() throws Exception {
long providerIndex = 9;
mSharedDataSource.setProviderIndex(providerIndex);
assertEquals(providerIndex, mSharedDataSource.getProviderIndex());
// Add a provider.
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
// Verify the provider ID used to create the new provider.
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), eq(providerIndex), eq(TEST_CREATOR_UID),
eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
assertTrue(
mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false, true));
verifyInstalledConfig(config);
reset(mWifiConfigManager);
}
/**
* Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
* adding a legacy Passpoint configuration containing a valid user credential.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithUserCredential() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String username = "username";
String password = "password";
byte[] base64EncodedPw =
Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
String caCertificateAlias = "CaCert";
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setIdentity(username);
wifiConfig.enterpriseConfig.setPassword(password);
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
// Setup expected {@link PasspointConfiguration}
PasspointConfiguration passpointConfig = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
homeSp.setRoamingConsortiumOis(rcOIs);
passpointConfig.setHomeSp(homeSp);
Credential credential = new Credential();
Credential.UserCredential userCredential = new Credential.UserCredential();
userCredential.setUsername(username);
userCredential.setPassword(encodedPasswordStr);
userCredential.setEapType(EAPConstants.EAP_TTLS);
userCredential.setNonEapInnerMethod("PAP");
credential.setUserCredential(userCredential);
credential.setRealm(realm);
passpointConfig.setCredential(credential);
assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
verifyInstalledConfig(passpointConfig);
}
/**
* Verify that adding a legacy Passpoint configuration containing user credential will
* fail when client certificate is not provided.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithUserCredentialWithoutCaCert() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String username = "username";
String password = "password";
byte[] base64EncodedPw =
Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setIdentity(username);
wifiConfig.enterpriseConfig.setPassword(password);
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
}
/**
* Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
* adding a legacy Passpoint configuration containing a valid SIM credential.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithSimCredential() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String imsi = "1234";
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
wifiConfig.enterpriseConfig.setPlmn(imsi);
// Setup expected {@link PasspointConfiguration}
PasspointConfiguration passpointConfig = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
homeSp.setRoamingConsortiumOis(rcOIs);
passpointConfig.setHomeSp(homeSp);
Credential credential = new Credential();
Credential.SimCredential simCredential = new Credential.SimCredential();
simCredential.setEapType(EAPConstants.EAP_SIM);
simCredential.setImsi(imsi);
credential.setSimCredential(simCredential);
credential.setRealm(realm);
passpointConfig.setCredential(credential);
assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
verifyInstalledConfig(passpointConfig);
}
/**
* Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
* adding a legacy Passpoint configuration containing a valid certificate credential.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithCertCredential() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String caCertificateAlias = "CaCert";
String clientCertificateAlias = "ClientCert";
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
// Setup expected {@link PasspointConfiguration}
PasspointConfiguration passpointConfig = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
homeSp.setRoamingConsortiumOis(rcOIs);
passpointConfig.setHomeSp(homeSp);
Credential credential = new Credential();
Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
credential.setCertCredential(certCredential);
credential.setRealm(realm);
passpointConfig.setCredential(credential);
assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
verifyInstalledConfig(passpointConfig);
}
/**
* Verify that adding a legacy Passpoint configuration containing certificate credential will
* fail when CA certificate is not provided.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithCertCredentialWithoutCaCert() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String clientCertificateAlias = "ClientCert";
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
}
/**
* Verify that adding a legacy Passpoint configuration containing certificate credential will
* fail when client certificate is not provided.
*
* @throws Exception
*/
@Test
public void addLegacyPasspointConfigWithCertCredentialWithoutClientCert() throws Exception {
// Test data.
String fqdn = "test.com";
String friendlyName = "Friendly Name";
long[] rcOIs = new long[] {0x1234L, 0x2345L};
String realm = "realm.com";
String caCertificateAlias = "CaCert";
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = fqdn;
wifiConfig.providerFriendlyName = friendlyName;
wifiConfig.roamingConsortiumIds = rcOIs;
wifiConfig.enterpriseConfig.setRealm(realm);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
}
/**
* Verify that the provider's "hasEverConnected" flag will be set to true and the associated
* metric is updated after the provider was used to successfully connect to a Passpoint
* network for the first time.
*
* @throws Exception
*/
@Test
public void providerNetworkConnectedFirstTime() throws Exception {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
when(provider.getHasEverConnected()).thenReturn(false);
mManager.onPasspointNetworkConnected(provider.getConfig().getUniqueId());
verify(provider).setHasEverConnected(eq(true));
}
/**
* Verify that the provider's "hasEverConnected" flag the associated metric is not updated
* after the provider was used to successfully connect to a Passpoint network for non-first
* time.
*
* @throws Exception
*/
@Test
public void providerNetworkConnectedNotFirstTime() throws Exception {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
when(provider.getHasEverConnected()).thenReturn(true);
mManager.onPasspointNetworkConnected(TEST_FQDN);
verify(provider, never()).setHasEverConnected(anyBoolean());
}
/**
* Verify that the expected Passpoint metrics are updated when
* {@link PasspointManager#updateMetrics} is invoked.
*
* @throws Exception
*/
@Test
public void updateMetrics() {
PasspointProvider provider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
ArgumentCaptor<Map<String, PasspointProvider>> argCaptor = ArgumentCaptor.forClass(
Map.class);
// Provider have not provided a successful network connection.
int expectedInstalledProviders = 1;
int expectedConnectedProviders = 0;
when(provider.getHasEverConnected()).thenReturn(false);
mManager.updateMetrics();
verify(mWifiMetrics).updateSavedPasspointProfiles(
eq(expectedInstalledProviders), eq(expectedConnectedProviders));
verify(mWifiMetrics).updateSavedPasspointProfilesInfo(argCaptor.capture());
assertEquals(expectedInstalledProviders, argCaptor.getValue().size());
assertEquals(provider, argCaptor.getValue().get(provider.getConfig().getUniqueId()));
reset(mWifiMetrics);
// Provider have provided a successful network connection.
expectedConnectedProviders = 1;
when(provider.getHasEverConnected()).thenReturn(true);
mManager.updateMetrics();
verify(mWifiMetrics).updateSavedPasspointProfiles(
eq(expectedInstalledProviders), eq(expectedConnectedProviders));
}
/**
* Verify Passpoint Manager's provisioning APIs by invoking methods in PasspointProvisioner for
* initiailization and provisioning a provider.
*/
@Test
public void verifyPasspointProvisioner() {
mManager.initializeProvisioner(mLooper.getLooper());
verify(mPasspointProvisioner).init(any(Looper.class));
when(mPasspointProvisioner.startSubscriptionProvisioning(anyInt(), any(OsuProvider.class),
any(IProvisioningCallback.class))).thenReturn(true);
OsuProvider osuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
assertEquals(true,
mManager.startSubscriptionProvisioning(TEST_UID, osuProvider, mCallback));
}
/**
* Verify that the corresponding Passpoint provider is removed when the app is disabled.
*/
@Test
public void verifyRemovingPasspointProfilesWhenAppIsDisabled() {
WifiConfiguration currentConfiguration = WifiConfigurationTestUtil.createPasspointNetwork();
currentConfiguration.FQDN = TEST_FQDN;
when(mClientModeImpl.getCurrentWifiConfiguration()).thenReturn(currentConfiguration);
PasspointProvider passpointProvider =
addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
currentConfiguration.setPasspointUniqueId(passpointProvider.getConfig().getUniqueId());
verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE),
mAppOpChangedListenerCaptor.capture());
assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size());
AppOpsManager.OnOpChangedListener listener = mAppOpChangedListenerCaptor.getValue();
assertNotNull(listener);
// Disallow change wifi state & ensure we remove the profiles from database.
when(mAppOpsManager.unsafeCheckOpNoThrow(
OPSTR_CHANGE_WIFI_STATE, TEST_CREATOR_UID,
TEST_PACKAGE))
.thenReturn(MODE_IGNORED);
listener.onOpChanged(OPSTR_CHANGE_WIFI_STATE, TEST_PACKAGE);
mLooper.dispatchAll();
verify(mAppOpsManager).stopWatchingMode(mAppOpChangedListenerCaptor.getValue());
verify(mClientModeImpl).disconnectCommand();
assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, true).isEmpty());
}
/**
* Verify that removing a provider with a different UID will not succeed.
*
* @throws Exception
*/
@Test
public void removeGetProviderWithDifferentUid() throws Exception {
PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verifyInstalledConfig(config);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// no profiles available for TEST_UID
assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty());
// 1 profile available for TEST_CREATOR_UID
assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
// Remove the provider as a non-privileged non-creator app.
assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN));
verify(provider, never()).uninstallCertsAndKeys();
verify(mWifiConfigManager, never()).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
// no profiles available for TEST_UID
assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty());
// 1 profile available for TEST_CREATOR_UID
assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
}
/**
* Verify that adding a suggestion provider with a valid configuration and user credential will
* succeed.
*
* @throws Exception
*/
@Test
public void addRemoveSuggestionProvider() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
when(provider.isFromSuggestion()).thenReturn(true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE),
eq(TEST_PACKAGE), any(AppOpsManager.OnOpChangedListener.class));
assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify content in the data source.
List<PasspointProvider> providers = mUserDataSource.getProviders();
assertEquals(1, providers.size());
assertEquals(config, providers.get(0).getConfig());
// Provider index start with 0, should be 1 after adding a provider.
assertEquals(1, mSharedDataSource.getProviderIndex());
// Remove from another Suggestor app, should fail.
assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN));
verify(provider, never()).uninstallCertsAndKeys();
verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
provider.getWifiConfig().getKey());
verify(mWifiConfigManager, never()).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
verify(mAppOpsManager, never()).stopWatchingMode(
any(AppOpsManager.OnOpChangedListener.class));
// Verify content in the data source.
providers = mUserDataSource.getProviders();
assertEquals(1, providers.size());
assertEquals(config, providers.get(0).getConfig());
// Provider index start with 0, should be 1 after adding a provider.
assertEquals(1, mSharedDataSource.getProviderIndex());
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Remove the provider from same app.
assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
verify(provider).uninstallCertsAndKeys();
verify(mWifiConfigManager).removePasspointConfiguredNetwork(
provider.getWifiConfig().getKey());
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
verify(mAppOpsManager, never()).stopWatchingMode(
any(AppOpsManager.OnOpChangedListener.class));
// Verify content in the data source.
assertTrue(mUserDataSource.getProviders().isEmpty());
// Removing a provider should not change the provider index.
assertEquals(1, mSharedDataSource.getProviderIndex());
}
/**
* Verify that adding a suggestion provider with the same base domain as the existing
* suggestion provider from same app will succeed, and verify that the new provider is
* added along with the existing provider.
*
* @throws Exception
*/
@Test
public void addSuggestionProviderWithExistingConfig() throws Exception {
// Add a provider with the original configuration.
PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify data source content.
List<PasspointProvider> origProviders = mUserDataSource.getProviders();
assertEquals(1, origProviders.size());
assertEquals(origConfig, origProviders.get(0).getConfig());
assertEquals(1, mSharedDataSource.getProviderIndex());
// Add same provider as existing suggestion provider
// This should be no WifiConfig deletion
WifiConfiguration origWifiConfig = origProvider.getWifiConfig();
origWifiConfig.fromWifiNetworkSuggestion = true;
origWifiConfig.creatorUid = TEST_CREATOR_UID;
origWifiConfig.creatorName = TEST_PACKAGE;
when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getKey()))
.thenReturn(origWifiConfig);
when(mWifiConfigManager.addOrUpdateNetwork(
origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
origWifiConfig.getKey());
verify(mWifiConfigManager).addOrUpdateNetwork(
argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE));
verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
assertEquals(2, mSharedDataSource.getProviderIndex());
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Add another provider with the same base domain as the existing saved provider.
// This should replace the existing provider with the new configuration.
PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(newProvider.isFromSuggestion()).thenReturn(true);
when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
// Verify data source content.
List<PasspointProvider> newProviders = mUserDataSource.getProviders();
assertEquals(2, newProviders.size());
assertTrue(newConfig.equals(newProviders.get(0).getConfig())
|| newConfig.equals(newProviders.get(1).getConfig()));
assertTrue(origConfig.equals(newProviders.get(0).getConfig())
|| origConfig.equals(newProviders.get(1).getConfig()));
assertEquals(3, mSharedDataSource.getProviderIndex());
}
/**
* Verify that adding a saved provider with the same base domain as the existing
* suggestion provider will succeed, and verify that the new provider with the new configuration
* is added along with the existing provider.
*
* @throws Exception
*/
@Test
public void addSavedProviderWithExistingSuggestionConfig() throws Exception {
// Add a provider with the original configuration.
PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
true, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify data source content.
List<PasspointProvider> origProviders = mUserDataSource.getProviders();
assertEquals(1, origProviders.size());
assertEquals(origConfig, origProviders.get(0).getConfig());
assertEquals(1, mSharedDataSource.getProviderIndex());
// Add another provider with the same base domain as the existing saved provider.
// This should replace the existing provider with the new configuration.
PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
false, true));
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
// Verify data source content.
List<PasspointProvider> newProviders = mUserDataSource.getProviders();
assertEquals(2, newProviders.size());
assertTrue(newConfig.equals(newProviders.get(0).getConfig())
|| newConfig.equals(newProviders.get(1).getConfig()));
assertTrue(origConfig.equals(newProviders.get(0).getConfig())
|| origConfig.equals(newProviders.get(1).getConfig()));
assertEquals(2, mSharedDataSource.getProviderIndex());
}
/**
* Verify that adding a suggestion provider with the same base domain as the existing provider
* from different apps will add a new provider.
*
* @throws Exception
*/
@Test
public void addSuggestionProviderWithExistingConfigFromDifferentSource() throws Exception {
// Add a provider with the original configuration.
PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false,
true));
verifyInstalledConfig(origConfig);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
reset(mWifiMetrics);
reset(mWifiConfigManager);
// Verify data source content.
List<PasspointProvider> origProviders = mUserDataSource.getProviders();
assertEquals(1, origProviders.size());
assertEquals(origConfig, origProviders.get(0).getConfig());
assertEquals(1, mSharedDataSource.getProviderIndex());
// Add another provider with the same base domain as the existing saved provider but from
// different app. This should not replace the existing provider with the new configuration
// but add another one.
PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(newProvider.isFromSuggestion()).thenReturn(true);
when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE1);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1),
eq(true))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE1, true,
true));
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
// Verify data source content.
List<PasspointProvider> newProviders = mUserDataSource.getProviders();
assertEquals(2, newProviders.size());
assertTrue(origConfig.equals(newProviders.get(0).getConfig())
|| origConfig.equals(newProviders.get(1).getConfig()));
assertEquals(2, mSharedDataSource.getProviderIndex());
}
/**
* Verify that the HomeProvider provider will be returned when a HomeProvider profile has
* not expired and RoamingProvider expiration is unset (still valid).
*
* @throws Exception
*/
@Test
public void matchHomeProviderWhenHomeProviderNotExpired() throws Exception {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
System.currentTimeMillis() + 100000);
providerHome.getWifiConfig().isHomeProviderNetwork = true;
PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
TEST_UID, "\"PasspointTestSSID\"", true, true,
TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, wifiConfiguration, false, null);
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
when(providerHome.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.HomeProvider);
when(providerRoaming.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.RoamingProvider);
when(providerNone.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.None);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
Pair<PasspointProvider, PasspointMatch> result = results.get(0);
assertEquals(PasspointMatch.HomeProvider, result.second);
assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
} finally {
session.finishMocking();
}
}
/**
* Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
* expired and RoamingProvider expiration is unset (still valid).
*
* @throws Exception
*/
@Test
public void matchRoamingProviderUnsetWhenHomeProviderExpired() throws Exception {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
System.currentTimeMillis() - 10000);
providerHome.getWifiConfig().isHomeProviderNetwork = true;
PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
TEST_UID, "\"PasspointTestSSID\"", true, true,
TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, wifiConfiguration, false, null);
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
when(providerHome.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.HomeProvider);
when(providerRoaming.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.RoamingProvider);
when(providerNone.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.None);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
Pair<PasspointProvider, PasspointMatch> result = results.get(0);
assertEquals(PasspointMatch.RoamingProvider, result.second);
assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
} finally {
session.finishMocking();
}
}
/**
* Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
* expired and RoamingProvider expiration is still valid.
*
* @throws Exception
*/
@Test
public void matchRoamingProviderNonExpiredWhenHomeProviderExpired() throws Exception {
// static mocking
MockitoSession session =
com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
InformationElementUtil.class).startMocking();
try {
PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
System.currentTimeMillis() - 10000);
providerHome.getWifiConfig().isHomeProviderNetwork = true;
PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, null);
providerRoaming.getConfig().setSubscriptionExpirationTimeInMillis(
System.currentTimeMillis() + 100000);
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
TEST_UID, "\"PasspointTestSSID\"", true, true,
TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE, wifiConfiguration, false, null);
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
when(providerHome.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.HomeProvider);
when(providerRoaming.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.RoamingProvider);
when(providerNone.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.None);
List<Pair<PasspointProvider, PasspointMatch>> results =
mManager.matchProvider(createTestScanResult());
Pair<PasspointProvider, PasspointMatch> result = results.get(0);
assertEquals(PasspointMatch.RoamingProvider, result.second);
assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
} finally {
session.finishMocking();
}
}
/**
* Verify add untrusted passpoint network from suggestion success.
*/
@Test
public void testAddUntrustedPasspointNetworkFromSuggestion() {
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = TEST_FQDN;
PasspointConfiguration config =
createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config, wifiConfig, true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
assertTrue(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
verify(provider).setTrusted(false);
}
/**
* Verify add untrusted passpoint network not from suggestion fail.
*/
@Test
public void testAddUntrustedPasspointNetworkNotFromSuggestion() {
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = TEST_FQDN;
PasspointConfiguration config =
createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config, wifiConfig, false);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
assertFalse(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, false, false));
verify(provider, never()).setTrusted(false);
}
/**
* Verify that the ScanResults(Access Points) are returned when it may be
* authenticated with the provided passpoint configuration as roaming match.
*/
@Test
public void getMatchingScanResultsTestWithRoamingMatch() {
PasspointConfiguration config = mock(PasspointConfiguration.class);
PasspointProvider mockProvider = mock(PasspointProvider.class);
when(mObjectFactory.makePasspointProvider(config, null,
mWifiCarrierInfoManager, 0, 0, null, false))
.thenReturn(mockProvider);
List<ScanResult> scanResults = new ArrayList<>() {{
add(mock(ScanResult.class));
}};
when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.RoamingProvider);
List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
assertEquals(1, testResults.size());
}
/**
* Verify that the ScanResults(Access Points) are returned when it may be
* authenticated with the provided passpoint configuration as home match.
*/
@Test
public void getMatchingScanResultsTestWithHomeMatch() {
PasspointConfiguration config = mock(PasspointConfiguration.class);
PasspointProvider mockProvider = mock(PasspointProvider.class);
when(mObjectFactory.makePasspointProvider(config, null,
mWifiCarrierInfoManager, 0, 0, null, false))
.thenReturn(mockProvider);
List<ScanResult> scanResults = new ArrayList<>() {{
add(mock(ScanResult.class));
}};
when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.HomeProvider);
List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
assertEquals(1, testResults.size());
}
/**
* Verify that the ScanResults(Access Points) are not returned when it cannot be
* authenticated with the provided passpoint configuration as none match.
*/
@Test
public void getMatchingScanResultsTestWithNonMatch() {
PasspointConfiguration config = mock(PasspointConfiguration.class);
PasspointProvider mockProvider = mock(PasspointProvider.class);
when(mObjectFactory.makePasspointProvider(config, null,
mWifiCarrierInfoManager, 0, 0, null, false))
.thenReturn(mockProvider);
List<ScanResult> scanResults = new ArrayList<>() {{
add(mock(ScanResult.class));
}};
when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
.thenReturn(PasspointMatch.None);
List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
assertEquals(0, testResults.size());
}
/**
* Verify that no ANQP queries are requested when not allowed (i.e. by WifiMetrics) when
* there is a cache miss.
*/
@Test
public void testAnqpRequestNotAllowed() {
reset(mWifiConfigManager);
when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(null);
verify(mAnqpRequestManager, never()).requestANQPElements(any(long.class),
any(ANQPNetworkKey.class), any(boolean.class), any(NetworkDetail.HSRelease.class));
}
/**
* Verify that removing of multiple providers with the same FQDN is done correctly.
*/
@Test
public void removeAllProvidersWithSameFqdn() {
PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, TEST_REALM);
PasspointProvider provider2 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, TEST_REALM2);
PasspointProvider provider3 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
TEST_PACKAGE, false, TEST_REALM3);
List<PasspointProvider> providers = mUserDataSource.getProviders();
assertEquals(3, providers.size());
verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallSuccess();
// Remove the provider as the creator app.
assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
verify(provider1).uninstallCertsAndKeys();
verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
provider1.getWifiConfig().getKey());
verify(provider2).uninstallCertsAndKeys();
verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
provider2.getWifiConfig().getKey());
verify(provider3).uninstallCertsAndKeys();
verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
provider3.getWifiConfig().getKey());
verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallSuccess();
verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class));
assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
// Verify content in the data source.
assertTrue(mUserDataSource.getProviders().isEmpty());
}
/**
* Verify that adding a provider with a self signed root CA increments the metrics correctly.
*
* @throws Exception
*/
@Test
public void verifySelfSignRootCaMetrics() throws Exception {
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = TEST_FQDN;
PasspointConfiguration config =
createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config, wifiConfig, true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
assertTrue(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
verify(mWifiMetrics).incrementNumPasspointProviderWithSelfSignedRootCa();
verify(mWifiMetrics, never()).incrementNumPasspointProviderWithNoRootCa();
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a provider with no root CA increments the metrics correctly.
*
* @throws Exception
*/
@Test
public void verifyNoRootCaMetrics() throws Exception {
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = TEST_FQDN;
PasspointConfiguration config =
createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
config.getCredential().setCaCertificate(null);
PasspointProvider provider = createMockProvider(config, wifiConfig, true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
assertTrue(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
verify(mWifiMetrics).incrementNumPasspointProviderWithNoRootCa();
verify(mWifiMetrics, never()).incrementNumPasspointProviderWithSelfSignedRootCa();
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
}
/**
* Verify that adding a provider with subscription expiration increments the metrics correctly.
*
* @throws Exception
*/
@Test
public void verifySubscriptionExpirationMetrics() throws Exception {
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.FQDN = TEST_FQDN;
PasspointConfiguration config =
createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
config.setSubscriptionExpirationTimeInMillis(1586228641000L);
PasspointProvider provider = createMockProvider(config, wifiConfig, true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
assertTrue(mManager.addOrUpdateProvider(
config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
verify(mWifiMetrics).incrementNumPasspointProviderWithSubscriptionExpiration();
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
}
}