Home | History | Annotate | Download | only in hotspot2
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wifi.hotspot2;
     18 
     19 import static android.net.wifi.WifiManager.ACTION_PASSPOINT_DEAUTH_IMMINENT;
     20 import static android.net.wifi.WifiManager.ACTION_PASSPOINT_ICON;
     21 import static android.net.wifi.WifiManager.ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION;
     22 import static android.net.wifi.WifiManager.EXTRA_BSSID_LONG;
     23 import static android.net.wifi.WifiManager.EXTRA_DELAY;
     24 import static android.net.wifi.WifiManager.EXTRA_ESS;
     25 import static android.net.wifi.WifiManager.EXTRA_FILENAME;
     26 import static android.net.wifi.WifiManager.EXTRA_ICON;
     27 import static android.net.wifi.WifiManager.EXTRA_SUBSCRIPTION_REMEDIATION_METHOD;
     28 import static android.net.wifi.WifiManager.EXTRA_URL;
     29 
     30 import static org.junit.Assert.assertEquals;
     31 import static org.junit.Assert.assertFalse;
     32 import static org.junit.Assert.assertNull;
     33 import static org.junit.Assert.assertTrue;
     34 import static org.mockito.Mockito.any;
     35 import static org.mockito.Mockito.anyBoolean;
     36 import static org.mockito.Mockito.anyInt;
     37 import static org.mockito.Mockito.anyLong;
     38 import static org.mockito.Mockito.anyMap;
     39 import static org.mockito.Mockito.doThrow;
     40 import static org.mockito.Mockito.eq;
     41 import static org.mockito.Mockito.mock;
     42 import static org.mockito.Mockito.never;
     43 import static org.mockito.Mockito.reset;
     44 import static org.mockito.Mockito.verify;
     45 import static org.mockito.Mockito.when;
     46 import static org.mockito.MockitoAnnotations.initMocks;
     47 
     48 import android.content.Context;
     49 import android.content.Intent;
     50 import android.graphics.drawable.Icon;
     51 import android.net.Uri;
     52 import android.net.wifi.EAPConstants;
     53 import android.net.wifi.ScanResult;
     54 import android.net.wifi.WifiConfiguration;
     55 import android.net.wifi.WifiEnterpriseConfig;
     56 import android.net.wifi.WifiManager;
     57 import android.net.wifi.WifiSsid;
     58 import android.net.wifi.hotspot2.IProvisioningCallback;
     59 import android.net.wifi.hotspot2.OsuProvider;
     60 import android.net.wifi.hotspot2.PasspointConfiguration;
     61 import android.net.wifi.hotspot2.pps.Credential;
     62 import android.net.wifi.hotspot2.pps.HomeSp;
     63 import android.os.Looper;
     64 import android.os.UserHandle;
     65 import android.os.test.TestLooper;
     66 import android.support.test.filters.SmallTest;
     67 import android.util.Base64;
     68 import android.util.Pair;
     69 
     70 import com.android.server.wifi.Clock;
     71 import com.android.server.wifi.FakeKeys;
     72 import com.android.server.wifi.IMSIParameter;
     73 import com.android.server.wifi.SIMAccessor;
     74 import com.android.server.wifi.WifiConfigManager;
     75 import com.android.server.wifi.WifiConfigStore;
     76 import com.android.server.wifi.WifiKeyStore;
     77 import com.android.server.wifi.WifiMetrics;
     78 import com.android.server.wifi.WifiNative;
     79 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
     80 import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
     81 import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
     82 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
     83 import com.android.server.wifi.hotspot2.anqp.I18Name;
     84 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
     85 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
     86 import com.android.server.wifi.util.ScanResultUtil;
     87 
     88 import org.junit.Before;
     89 import org.junit.Test;
     90 import org.mockito.ArgumentCaptor;
     91 import org.mockito.Mock;
     92 
     93 import java.nio.charset.StandardCharsets;
     94 import java.security.GeneralSecurityException;
     95 import java.security.KeyStore;
     96 import java.security.cert.X509Certificate;
     97 import java.util.ArrayList;
     98 import java.util.Arrays;
     99 import java.util.HashMap;
    100 import java.util.List;
    101 import java.util.Locale;
    102 import java.util.Map;
    103 
    104 /**
    105  * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointManager}.
    106  */
    107 @SmallTest
    108 public class PasspointManagerTest {
    109     private static final long BSSID = 0x112233445566L;
    110     private static final String ICON_FILENAME = "test";
    111     private static final String  TEST_FQDN = "test1.test.com";
    112     private static final String TEST_FRIENDLY_NAME = "friendly name";
    113     private static final String TEST_REALM = "realm.test.com";
    114     private static final String TEST_IMSI = "1234*";
    115     private static final IMSIParameter TEST_IMSI_PARAM = IMSIParameter.build(TEST_IMSI);
    116 
    117     private static final String TEST_SSID = "TestSSID";
    118     private static final long TEST_BSSID = 0x112233445566L;
    119     private static final String TEST_BSSID_STRING = "11:22:33:44:55:66";
    120     private static final long TEST_HESSID = 0x5678L;
    121     private static final int TEST_ANQP_DOMAIN_ID = 0;
    122     private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey(
    123             TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID);
    124     private static final int TEST_CREATOR_UID = 1234;
    125     private static final int TEST_UID = 1500;
    126 
    127     @Mock Context mContext;
    128     @Mock WifiNative mWifiNative;
    129     @Mock WifiKeyStore mWifiKeyStore;
    130     @Mock Clock mClock;
    131     @Mock SIMAccessor mSimAccessor;
    132     @Mock PasspointObjectFactory mObjectFactory;
    133     @Mock PasspointEventHandler.Callbacks mCallbacks;
    134     @Mock AnqpCache mAnqpCache;
    135     @Mock ANQPRequestManager mAnqpRequestManager;
    136     @Mock CertificateVerifier mCertVerifier;
    137     @Mock WifiConfigManager mWifiConfigManager;
    138     @Mock WifiConfigStore mWifiConfigStore;
    139     @Mock PasspointConfigStoreData.DataSource mDataSource;
    140     @Mock WifiMetrics mWifiMetrics;
    141     @Mock OsuNetworkConnection mOsuNetworkConnection;
    142     @Mock OsuServerConnection mOsuServerConnection;
    143     @Mock PasspointProvisioner mPasspointProvisioner;
    144     @Mock IProvisioningCallback mCallback;
    145     @Mock WfaKeyStore mWfaKeyStore;
    146     @Mock KeyStore mKeyStore;
    147 
    148     TestLooper mLooper;
    149     PasspointManager mManager;
    150 
    151     /** Sets up test. */
    152     @Before
    153     public void setUp() throws Exception {
    154         initMocks(this);
    155         when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache);
    156         when(mObjectFactory.makeANQPRequestManager(any(), eq(mClock)))
    157                 .thenReturn(mAnqpRequestManager);
    158         when(mObjectFactory.makeCertificateVerifier()).thenReturn(mCertVerifier);
    159         when(mObjectFactory.makeOsuNetworkConnection(any(Context.class)))
    160                 .thenReturn(mOsuNetworkConnection);
    161         when(mObjectFactory.makeOsuServerConnection())
    162                 .thenReturn(mOsuServerConnection);
    163         when(mObjectFactory.makeWfaKeyStore()).thenReturn(mWfaKeyStore);
    164         when(mWfaKeyStore.get()).thenReturn(mKeyStore);
    165         when(mObjectFactory.makePasspointProvisioner(any(Context.class)))
    166                 .thenReturn(mPasspointProvisioner);
    167         mManager = new PasspointManager(mContext, mWifiNative, mWifiKeyStore, mClock,
    168                 mSimAccessor, mObjectFactory, mWifiConfigManager, mWifiConfigStore, mWifiMetrics);
    169         ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks =
    170                 ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class);
    171         verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class),
    172                                                          callbacks.capture());
    173         ArgumentCaptor<PasspointConfigStoreData.DataSource> dataSource =
    174                 ArgumentCaptor.forClass(PasspointConfigStoreData.DataSource.class);
    175         verify(mObjectFactory).makePasspointConfigStoreData(
    176                 any(WifiKeyStore.class), any(SIMAccessor.class), dataSource.capture());
    177         mCallbacks = callbacks.getValue();
    178         mDataSource = dataSource.getValue();
    179         mLooper = new TestLooper();
    180     }
    181 
    182     /**
    183      * Verify {@link WifiManager#ACTION_PASSPOINT_ICON} broadcast intent.
    184      * @param bssid BSSID of the AP
    185      * @param fileName Name of the icon file
    186      * @param data icon data byte array
    187      */
    188     private void verifyIconIntent(long bssid, String fileName, byte[] data) {
    189         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
    190         verify(mContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL),
    191                 eq(android.Manifest.permission.ACCESS_WIFI_STATE));
    192         assertEquals(ACTION_PASSPOINT_ICON, intent.getValue().getAction());
    193         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_BSSID_LONG));
    194         assertEquals(bssid, intent.getValue().getExtras().getLong(EXTRA_BSSID_LONG));
    195         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_FILENAME));
    196         assertEquals(fileName, intent.getValue().getExtras().getString(EXTRA_FILENAME));
    197         if (data != null) {
    198             assertTrue(intent.getValue().getExtras().containsKey(EXTRA_ICON));
    199             Icon icon = (Icon) intent.getValue().getExtras().getParcelable(EXTRA_ICON);
    200             assertTrue(Arrays.equals(data, icon.getDataBytes()));
    201         } else {
    202             assertFalse(intent.getValue().getExtras().containsKey(EXTRA_ICON));
    203         }
    204     }
    205 
    206     /**
    207      * Verify that the given Passpoint configuration matches the one that's added to
    208      * the PasspointManager.
    209      *
    210      * @param expectedConfig The expected installed Passpoint configuration
    211      */
    212     private void verifyInstalledConfig(PasspointConfiguration expectedConfig) {
    213         List<PasspointConfiguration> installedConfigs = mManager.getProviderConfigs();
    214         assertEquals(1, installedConfigs.size());
    215         assertEquals(expectedConfig, installedConfigs.get(0));
    216     }
    217 
    218     /**
    219      * Create a mock PasspointProvider with default expectations.
    220      *
    221      * @param config The configuration associated with the provider
    222      * @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
    223      */
    224     private PasspointProvider createMockProvider(PasspointConfiguration config) {
    225         PasspointProvider provider = mock(PasspointProvider.class);
    226         when(provider.installCertsAndKeys()).thenReturn(true);
    227         when(provider.getConfig()).thenReturn(config);
    228         return provider;
    229     }
    230 
    231     /**
    232      * Helper function for creating a test configuration with user credential.
    233      *
    234      * @return {@link PasspointConfiguration}
    235      */
    236     private PasspointConfiguration createTestConfigWithUserCredential(String fqdn) {
    237         PasspointConfiguration config = new PasspointConfiguration();
    238         HomeSp homeSp = new HomeSp();
    239         homeSp.setFqdn(fqdn);
    240         homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
    241         config.setHomeSp(homeSp);
    242         Credential credential = new Credential();
    243         credential.setRealm(TEST_REALM);
    244         credential.setCaCertificate(FakeKeys.CA_CERT0);
    245         Credential.UserCredential userCredential = new Credential.UserCredential();
    246         userCredential.setUsername("username");
    247         userCredential.setPassword("password");
    248         userCredential.setEapType(EAPConstants.EAP_TTLS);
    249         userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAP);
    250         credential.setUserCredential(userCredential);
    251         config.setCredential(credential);
    252         return config;
    253     }
    254 
    255     /**
    256      * Helper function for creating a test configuration with SIM credential.
    257      *
    258      * @return {@link PasspointConfiguration}
    259      */
    260     private PasspointConfiguration createTestConfigWithSimCredential() {
    261         PasspointConfiguration config = new PasspointConfiguration();
    262         HomeSp homeSp = new HomeSp();
    263         homeSp.setFqdn(TEST_FQDN);
    264         homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
    265         config.setHomeSp(homeSp);
    266         Credential credential = new Credential();
    267         credential.setRealm(TEST_REALM);
    268         Credential.SimCredential simCredential = new Credential.SimCredential();
    269         simCredential.setImsi(TEST_IMSI);
    270         simCredential.setEapType(EAPConstants.EAP_SIM);
    271         credential.setSimCredential(simCredential);
    272         config.setCredential(credential);
    273         return config;
    274     }
    275 
    276     /**
    277      * Helper function for adding a test provider to the manager.  Return the mock
    278      * provider that's added to the manager.
    279      *
    280      * @return {@link PasspointProvider}
    281      */
    282     private PasspointProvider addTestProvider(String fqdn) {
    283         PasspointConfiguration config = createTestConfigWithUserCredential(fqdn);
    284         PasspointProvider provider = createMockProvider(config);
    285         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
    286                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(provider);
    287         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    288 
    289         return provider;
    290     }
    291 
    292     /**
    293      * Helper function for creating a ScanResult for testing.
    294      *
    295      * @return {@link ScanResult}
    296      */
    297     private ScanResult createTestScanResult() {
    298         ScanResult scanResult = new ScanResult();
    299         scanResult.SSID = TEST_SSID;
    300         scanResult.BSSID = TEST_BSSID_STRING;
    301         scanResult.hessid = TEST_HESSID;
    302         scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
    303         return scanResult;
    304     }
    305 
    306     /**
    307      * Verify that the ANQP elements will be added to the ANQP cache on receiving a successful
    308      * response.
    309      *
    310      * @throws Exception
    311      */
    312     @Test
    313     public void anqpResponseSuccess() throws Exception {
    314         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
    315         anqpElementMap.put(ANQPElementType.ANQPDomName,
    316                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
    317 
    318         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY);
    319         mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
    320         verify(mAnqpCache).addEntry(TEST_ANQP_KEY, anqpElementMap);
    321         verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
    322                 any(String.class));
    323     }
    324 
    325     /**
    326      * Verify that no ANQP elements will be added to the ANQP cache on receiving a successful
    327      * response for a request that's not sent by us.
    328      *
    329      * @throws Exception
    330      */
    331     @Test
    332     public void anqpResponseSuccessWithUnknownRequest() throws Exception {
    333         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
    334         anqpElementMap.put(ANQPElementType.ANQPDomName,
    335                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
    336 
    337         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null);
    338         mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
    339         verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
    340     }
    341 
    342     /**
    343      * Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response.
    344      *
    345      * @throws Exception
    346      */
    347     @Test
    348     public void anqpResponseFailure() throws Exception {
    349         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY);
    350         mCallbacks.onANQPResponse(TEST_BSSID, null);
    351         verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
    352 
    353     }
    354 
    355     /**
    356      * Validate the broadcast intent when icon file retrieval succeeded.
    357      *
    358      * @throws Exception
    359      */
    360     @Test
    361     public void iconResponseSuccess() throws Exception {
    362         byte[] iconData = new byte[] {0x00, 0x11};
    363         mCallbacks.onIconResponse(BSSID, ICON_FILENAME, iconData);
    364         verifyIconIntent(BSSID, ICON_FILENAME, iconData);
    365     }
    366 
    367     /**
    368      * Validate the broadcast intent when icon file retrieval failed.
    369      *
    370      * @throws Exception
    371      */
    372     @Test
    373     public void iconResponseFailure() throws Exception {
    374         mCallbacks.onIconResponse(BSSID, ICON_FILENAME, null);
    375         verifyIconIntent(BSSID, ICON_FILENAME, null);
    376     }
    377 
    378     /**
    379      * Validate the broadcast intent {@link WifiManager#ACTION_PASSPOINT_DEAUTH_IMMINENT} when
    380      * Deauth Imminent WNM frame is received.
    381      *
    382      * @throws Exception
    383      */
    384     @Test
    385     public void onDeauthImminentReceived() throws Exception {
    386         String reasonUrl = "test.com";
    387         int delay = 123;
    388         boolean ess = true;
    389 
    390         mCallbacks.onWnmFrameReceived(new WnmData(BSSID, reasonUrl, ess, delay));
    391         // Verify the broadcast intent.
    392         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
    393         verify(mContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL),
    394                 eq(android.Manifest.permission.ACCESS_WIFI_STATE));
    395         assertEquals(ACTION_PASSPOINT_DEAUTH_IMMINENT, intent.getValue().getAction());
    396         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_BSSID_LONG));
    397         assertEquals(BSSID, intent.getValue().getExtras().getLong(EXTRA_BSSID_LONG));
    398         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_ESS));
    399         assertEquals(ess, intent.getValue().getExtras().getBoolean(EXTRA_ESS));
    400         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_DELAY));
    401         assertEquals(delay, intent.getValue().getExtras().getInt(EXTRA_DELAY));
    402         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_URL));
    403         assertEquals(reasonUrl, intent.getValue().getExtras().getString(EXTRA_URL));
    404     }
    405 
    406     /**
    407      * Validate the broadcast intent {@link WifiManager#ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION}
    408      * when Subscription Remediation WNM frame is received.
    409      *
    410      * @throws Exception
    411      */
    412     @Test
    413     public void onSubscriptionRemediationReceived() throws Exception {
    414         int serverMethod = 1;
    415         String serverUrl = "testUrl";
    416 
    417         mCallbacks.onWnmFrameReceived(new WnmData(BSSID, serverUrl, serverMethod));
    418         // Verify the broadcast intent.
    419         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
    420         verify(mContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL),
    421                 eq(android.Manifest.permission.ACCESS_WIFI_STATE));
    422         assertEquals(ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION, intent.getValue().getAction());
    423         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_BSSID_LONG));
    424         assertEquals(BSSID, intent.getValue().getExtras().getLong(EXTRA_BSSID_LONG));
    425         assertTrue(intent.getValue().getExtras().containsKey(
    426                 EXTRA_SUBSCRIPTION_REMEDIATION_METHOD));
    427         assertEquals(serverMethod, intent.getValue().getExtras().getInt(
    428                 EXTRA_SUBSCRIPTION_REMEDIATION_METHOD));
    429         assertTrue(intent.getValue().getExtras().containsKey(EXTRA_URL));
    430         assertEquals(serverUrl, intent.getValue().getExtras().getString(EXTRA_URL));
    431     }
    432 
    433     /**
    434      * Verify that adding a provider with a null configuration will fail.
    435      *
    436      * @throws Exception
    437      */
    438     @Test
    439     public void addProviderWithNullConfig() throws Exception {
    440         assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID));
    441         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    442         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
    443     }
    444 
    445     /**
    446      * Verify that adding a provider with a empty configuration will fail.
    447      *
    448      * @throws Exception
    449      */
    450     @Test
    451     public void addProviderWithEmptyConfig() throws Exception {
    452         assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID));
    453         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    454         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
    455     }
    456 
    457     /**
    458      * Verify taht adding a provider with an invalid credential will fail (using EAP-TLS
    459      * for user credential).
    460      *
    461      * @throws Exception
    462      */
    463     @Test
    464     public void addProviderWithInvalidCredential() throws Exception {
    465         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
    466         // EAP-TLS not allowed for user credential.
    467         config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS);
    468         assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    469         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    470         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
    471     }
    472 
    473     /**
    474      * Verify that adding a provider with a valid configuration and user credential will succeed.
    475      *
    476      * @throws Exception
    477      */
    478     @Test
    479     public void addRemoveProviderWithValidUserCredential() throws Exception {
    480         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
    481         PasspointProvider provider = createMockProvider(config);
    482         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
    483                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(provider);
    484         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    485         verifyInstalledConfig(config);
    486         verify(mWifiConfigManager).saveToStore(true);
    487         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    488         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
    489         reset(mWifiMetrics);
    490         reset(mWifiConfigManager);
    491 
    492         // Verify content in the data source.
    493         List<PasspointProvider> providers = mDataSource.getProviders();
    494         assertEquals(1, providers.size());
    495         assertEquals(config, providers.get(0).getConfig());
    496         // Provider index start with 0, should be 1 after adding a provider.
    497         assertEquals(1, mDataSource.getProviderIndex());
    498 
    499         // Remove the provider.
    500         assertTrue(mManager.removeProvider(TEST_FQDN));
    501         verify(provider).uninstallCertsAndKeys();
    502         verify(mWifiConfigManager).saveToStore(true);
    503         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
    504         verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
    505         assertTrue(mManager.getProviderConfigs().isEmpty());
    506 
    507         // Verify content in the data source.
    508         assertTrue(mDataSource.getProviders().isEmpty());
    509         // Removing a provider should not change the provider index.
    510         assertEquals(1, mDataSource.getProviderIndex());
    511     }
    512 
    513     /**
    514      * Verify that adding a provider with a valid configuration and SIM credential will succeed.
    515      *
    516      * @throws Exception
    517      */
    518     @Test
    519     public void addRemoveProviderWithValidSimCredential() throws Exception {
    520         PasspointConfiguration config = createTestConfigWithSimCredential();
    521         PasspointProvider provider = createMockProvider(config);
    522         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
    523                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(provider);
    524         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    525         verifyInstalledConfig(config);
    526         verify(mWifiConfigManager).saveToStore(true);
    527         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    528         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
    529         reset(mWifiMetrics);
    530         reset(mWifiConfigManager);
    531 
    532         // Verify content in the data source.
    533         List<PasspointProvider> providers = mDataSource.getProviders();
    534         assertEquals(1, providers.size());
    535         assertEquals(config, providers.get(0).getConfig());
    536         // Provider index start with 0, should be 1 after adding a provider.
    537         assertEquals(1, mDataSource.getProviderIndex());
    538 
    539         // Remove the provider.
    540         assertTrue(mManager.removeProvider(TEST_FQDN));
    541         verify(provider).uninstallCertsAndKeys();
    542         verify(mWifiConfigManager).saveToStore(true);
    543         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
    544         verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
    545         assertTrue(mManager.getProviderConfigs().isEmpty());
    546 
    547         // Verify content in the data source.
    548         assertTrue(mDataSource.getProviders().isEmpty());
    549         // Removing a provider should not change the provider index.
    550         assertEquals(1, mDataSource.getProviderIndex());
    551     }
    552 
    553     /**
    554      * Verify that adding a provider with the same base domain as the existing provider will
    555      * succeed, and verify that the existing provider is replaced by the new provider with
    556      * the new configuration.
    557      *
    558      * @throws Exception
    559      */
    560     @Test
    561     public void addProviderWithExistingConfig() throws Exception {
    562         // Add a provider with the original configuration.
    563         PasspointConfiguration origConfig = createTestConfigWithSimCredential();
    564         PasspointProvider origProvider = createMockProvider(origConfig);
    565         when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
    566                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(origProvider);
    567         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID));
    568         verifyInstalledConfig(origConfig);
    569         verify(mWifiConfigManager).saveToStore(true);
    570         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    571         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
    572         reset(mWifiMetrics);
    573         reset(mWifiConfigManager);
    574 
    575         // Verify data source content.
    576         List<PasspointProvider> origProviders = mDataSource.getProviders();
    577         assertEquals(1, origProviders.size());
    578         assertEquals(origConfig, origProviders.get(0).getConfig());
    579         assertEquals(1, mDataSource.getProviderIndex());
    580 
    581         // Add another provider with the same base domain as the existing provider.
    582         // This should replace the existing provider with the new configuration.
    583         PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN);
    584         PasspointProvider newProvider = createMockProvider(newConfig);
    585         when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
    586                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(newProvider);
    587         assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID));
    588         verifyInstalledConfig(newConfig);
    589         verify(mWifiConfigManager).saveToStore(true);
    590         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    591         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
    592 
    593         // Verify data source content.
    594         List<PasspointProvider> newProviders = mDataSource.getProviders();
    595         assertEquals(1, newProviders.size());
    596         assertEquals(newConfig, newProviders.get(0).getConfig());
    597         assertEquals(2, mDataSource.getProviderIndex());
    598     }
    599 
    600     /**
    601      * Verify that adding a provider will fail when failing to install certificates and
    602      * key to the keystore.
    603      *
    604      * @throws Exception
    605      */
    606     @Test
    607     public void addProviderOnKeyInstallationFailiure() throws Exception {
    608         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
    609         PasspointProvider provider = mock(PasspointProvider.class);
    610         when(provider.installCertsAndKeys()).thenReturn(false);
    611         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
    612                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(provider);
    613         assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    614         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    615         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
    616     }
    617 
    618     /**
    619      * Verify that adding a provider with an invalid CA certificate will fail.
    620      *
    621      * @throws Exception
    622      */
    623     @Test
    624     public void addProviderWithInvalidCaCert() throws Exception {
    625         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
    626         doThrow(new GeneralSecurityException())
    627                 .when(mCertVerifier).verifyCaCert(any(X509Certificate.class));
    628         assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    629         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    630         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
    631     }
    632 
    633     /**
    634      * Verify that adding a provider with R2 configuration will not perform CA certificate
    635      * verification.
    636      *
    637      * @throws Exception
    638      */
    639     @Test
    640     public void addProviderWithR2Config() throws Exception {
    641         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
    642         config.setUpdateIdentifier(1);
    643         PasspointProvider provider = createMockProvider(config);
    644         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
    645                 eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID))).thenReturn(provider);
    646         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
    647         verify(mCertVerifier, never()).verifyCaCert(any(X509Certificate.class));
    648         verifyInstalledConfig(config);
    649         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
    650         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
    651     }
    652 
    653     /**
    654      * Verify that removing a non-existing provider will fail.
    655      *
    656      * @throws Exception
    657      */
    658     @Test
    659     public void removeNonExistingProvider() throws Exception {
    660         assertFalse(mManager.removeProvider(TEST_FQDN));
    661         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
    662         verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
    663     }
    664 
    665     /**
    666      * Verify that a {code null} will be returned when no providers are installed.
    667      *
    668      * @throws Exception
    669      */
    670     @Test
    671     public void matchProviderWithNoProvidersInstalled() throws Exception {
    672         assertNull(mManager.matchProvider(createTestScanResult()));
    673     }
    674 
    675     /**
    676      * Verify that a {code null} be returned when ANQP entry doesn't exist in the cache.
    677      *
    678      * @throws Exception
    679      */
    680     @Test
    681     public void matchProviderWithAnqpCacheMissed() throws Exception {
    682         addTestProvider(TEST_FQDN);
    683 
    684         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
    685         assertNull(mManager.matchProvider(createTestScanResult()));
    686         // Verify that a request for ANQP elements is initiated.
    687         verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), any(ANQPNetworkKey.class),
    688                 anyBoolean(), anyBoolean());
    689     }
    690 
    691     /**
    692      * Verify that the expected provider will be returned when a HomeProvider is matched.
    693      *
    694      * @throws Exception
    695      */
    696     @Test
    697     public void matchProviderAsHomeProvider() throws Exception {
    698         PasspointProvider provider = addTestProvider(TEST_FQDN);
    699         ANQPData entry = new ANQPData(mClock, null);
    700 
    701         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    702         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    703             .thenReturn(PasspointMatch.HomeProvider);
    704         Pair<PasspointProvider, PasspointMatch> result =
    705                 mManager.matchProvider(createTestScanResult());
    706         assertEquals(PasspointMatch.HomeProvider, result.second);
    707         assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
    708     }
    709 
    710     /**
    711      * Verify that the expected provider will be returned when a RoamingProvider is matched.
    712      *
    713      * @throws Exception
    714      */
    715     @Test
    716     public void matchProviderAsRoamingProvider() throws Exception {
    717         PasspointProvider provider = addTestProvider(TEST_FQDN);
    718         ANQPData entry = new ANQPData(mClock, null);
    719 
    720         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    721         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    722             .thenReturn(PasspointMatch.RoamingProvider);
    723         Pair<PasspointProvider, PasspointMatch> result =
    724                 mManager.matchProvider(createTestScanResult());
    725         assertEquals(PasspointMatch.RoamingProvider, result.second);
    726         assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
    727     }
    728 
    729     /**
    730      * Verify that a {code null} will be returned when there is no matching provider.
    731      *
    732      * @throws Exception
    733      */
    734     @Test
    735     public void matchProviderWithNoMatch() throws Exception {
    736         PasspointProvider provider = addTestProvider(TEST_FQDN);
    737         ANQPData entry = new ANQPData(mClock, null);
    738 
    739         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    740         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    741             .thenReturn(PasspointMatch.None);
    742         assertNull(mManager.matchProvider(createTestScanResult()));
    743     }
    744 
    745     /**
    746      * Verify the expectations for sweepCache.
    747      *
    748      * @throws Exception
    749      */
    750     @Test
    751     public void sweepCache() throws Exception {
    752         mManager.sweepCache();
    753         verify(mAnqpCache).sweep();
    754     }
    755 
    756     /**
    757      * Verify that an empty map will be returned if ANQP elements are not cached for the given AP.
    758      *
    759      * @throws Exception
    760      */
    761     @Test
    762     public void getANQPElementsWithNoMatchFound() throws Exception {
    763         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
    764         assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty());
    765     }
    766 
    767     /**
    768      * Verify that an expected ANQP elements will be returned if ANQP elements are cached for the
    769      * given AP.
    770      *
    771      * @throws Exception
    772      */
    773     @Test
    774     public void getANQPElementsWithMatchFound() throws Exception {
    775         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
    776         anqpElementMap.put(ANQPElementType.ANQPDomName,
    777                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
    778         ANQPData entry = new ANQPData(mClock, anqpElementMap);
    779 
    780         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    781         assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult()));
    782     }
    783 
    784     /**
    785      * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult}
    786      * is matched to a home provider.
    787      *
    788      * @throws Exception
    789      */
    790     @Test
    791     public void getMatchingWifiConfigForHomeProviderAP() throws Exception {
    792         PasspointProvider provider = addTestProvider(TEST_FQDN);
    793         ANQPData entry = new ANQPData(mClock, null);
    794 
    795         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    796         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    797             .thenReturn(PasspointMatch.HomeProvider);
    798         when(provider.getWifiConfig()).thenReturn(new WifiConfiguration());
    799         WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult());
    800         assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID);
    801         assertTrue(config.isHomeProviderNetwork);
    802     }
    803 
    804     /**
    805      * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult}
    806      * is matched to a roaming provider.
    807      *
    808      * @throws Exception
    809      */
    810     @Test
    811     public void getMatchingWifiConfigForRoamingProviderAP() throws Exception {
    812         PasspointProvider provider = addTestProvider(TEST_FQDN);
    813         ANQPData entry = new ANQPData(mClock, null);
    814 
    815         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    816         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    817             .thenReturn(PasspointMatch.RoamingProvider);
    818         when(provider.getWifiConfig()).thenReturn(new WifiConfiguration());
    819         WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult());
    820         assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID);
    821         assertFalse(config.isHomeProviderNetwork);
    822     }
    823 
    824     /**
    825      * Verify that a {code null} will be returned when a {@link ScanResult} doesn't match any
    826      * provider.
    827      *
    828      * @throws Exception
    829      */
    830     @Test
    831     public void getMatchingWifiConfigWithNoMatchingProvider() throws Exception {
    832         PasspointProvider provider = addTestProvider(TEST_FQDN);
    833         ANQPData entry = new ANQPData(mClock, null);
    834 
    835         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    836         when(provider.match(anyMap(), any(RoamingConsortium.class)))
    837             .thenReturn(PasspointMatch.None);
    838         assertNull(mManager.getMatchingWifiConfig(createTestScanResult()));
    839         verify(provider, never()).getWifiConfig();
    840     }
    841 
    842     /**
    843      * Verify that a {@code null} will be returned when trying to get a matching
    844      * {@link WifiConfiguration} for a {@code null} {@link ScanResult}.
    845      *
    846      * @throws Exception
    847      */
    848     @Test
    849     public void getMatchingWifiConfigWithNullScanResult() throws Exception {
    850         assertNull(mManager.getMatchingWifiConfig(null));
    851     }
    852 
    853     /**
    854      * Verify that a {@code null} will be returned when trying to get a matching
    855      * {@link WifiConfiguration} for a {@link ScanResult} with a {@code null} BSSID.
    856      *
    857      * @throws Exception
    858      */
    859     @Test
    860     public void getMatchingWifiConfigWithNullBSSID() throws Exception {
    861         ScanResult scanResult = createTestScanResult();
    862         scanResult.BSSID = null;
    863         assertNull(mManager.getMatchingWifiConfig(scanResult));
    864     }
    865 
    866     /**
    867      * Verify that a {@code null} will be returned when trying to get a matching
    868      * {@link WifiConfiguration} for a {@link ScanResult} with an invalid BSSID.
    869      *
    870      * @throws Exception
    871      */
    872     @Test
    873     public void getMatchingWifiConfigWithInvalidBSSID() throws Exception {
    874         ScanResult scanResult = createTestScanResult();
    875         scanResult.BSSID = "asdfdasfas";
    876         assertNull(mManager.getMatchingWifiConfig(scanResult));
    877     }
    878 
    879     /**
    880      * Verify that a {@code null} will be returned when trying to get a matching
    881      * {@link WifiConfiguration} for a non-Passpoint AP.
    882      *
    883      * @throws Exception
    884      */
    885     @Test
    886     public void getMatchingWifiConfigForNonPasspointAP() throws Exception {
    887         ScanResult scanResult = createTestScanResult();
    888         scanResult.flags = 0;
    889         assertNull(mManager.getMatchingWifiConfig(scanResult));
    890     }
    891 
    892     /**
    893      * Verify that an expected set of {@link WifiConfiguration} will be returned when a
    894      * {@link ScanResult} is matched to a provider.
    895      *
    896      * @throws Exception
    897      */
    898     @Test
    899     public void getAllMatchingWifiConfigsForProviderAP() throws Exception {
    900         PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0);
    901         PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1);
    902         PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2);
    903         ANQPData entry = new ANQPData(mClock, null);
    904 
    905         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
    906 
    907         when(providerHome.match(anyMap(), any(RoamingConsortium.class)))
    908             .thenReturn(PasspointMatch.HomeProvider);
    909         when(providerRoaming.match(anyMap(), any(RoamingConsortium.class)))
    910             .thenReturn(PasspointMatch.RoamingProvider);
    911         when(providerNone.match(anyMap(), any(RoamingConsortium.class)))
    912             .thenReturn(PasspointMatch.None);
    913 
    914         when(providerHome.getWifiConfig()).thenReturn(new WifiConfiguration());
    915         when(providerRoaming.getWifiConfig()).thenReturn(new WifiConfiguration());
    916         when(providerNone.getWifiConfig()).thenReturn(new WifiConfiguration());
    917 
    918         List<WifiConfiguration> configs = mManager.getAllMatchingWifiConfigs(
    919                 createTestScanResult());
    920 
    921         assertEquals(2, configs.size());
    922         int observedHome = 0;
    923         int observedRoaming = 0;
    924         for (WifiConfiguration config : configs) {
    925             assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID);
    926             if (config.isHomeProviderNetwork) {
    927                 observedHome++;
    928             } else {
    929                 observedRoaming++;
    930             }
    931         }
    932         assertEquals(1, observedHome);
    933         assertEquals(1, observedRoaming);
    934     }
    935 
    936     /**
    937      * Verify that an empty list will be returned when trying to get all matching
    938      * {@link WifiConfiguration} for a {@code null} {@link ScanResult}.
    939      *
    940      * @throws Exception
    941      */
    942     @Test
    943     public void getAllMatchingWifiConfigsWithNullScanResult() throws Exception {
    944         assertEquals(0, mManager.getAllMatchingWifiConfigs(null).size());
    945     }
    946 
    947     /**
    948      * Verify that an empty list will be returned when trying to get a all matching
    949      * {@link WifiConfiguration} for a {@link ScanResult} with a {@code null} BSSID.
    950      *
    951      * @throws Exception
    952      */
    953     @Test
    954     public void getAllMatchingWifiConfigWithNullBSSID() throws Exception {
    955         ScanResult scanResult = createTestScanResult();
    956         scanResult.BSSID = null;
    957         assertEquals(0, mManager.getAllMatchingWifiConfigs(scanResult).size());
    958     }
    959 
    960     /**
    961      * Verify that an empty list will be returned when trying to get all matching
    962      * {@link WifiConfiguration} for a {@link ScanResult} with an invalid BSSID.
    963      *
    964      * @throws Exception
    965      */
    966     @Test
    967     public void getAllMatchingWifiConfigWithInvalidBSSID() throws Exception {
    968         ScanResult scanResult = createTestScanResult();
    969         scanResult.BSSID = "asdfdasfas";
    970         assertEquals(0, mManager.getAllMatchingWifiConfigs(scanResult).size());
    971     }
    972 
    973     /**
    974      * Verify that an empty list will be returned when trying to get all matching
    975      * {@link WifiConfiguration} for a non-Passpoint AP.
    976      *
    977      * @throws Exception
    978      */
    979     @Test
    980     public void getAllMatchingWifiConfigForNonPasspointAP() throws Exception {
    981         ScanResult scanResult = createTestScanResult();
    982         scanResult.flags = 0;
    983         assertEquals(0, mManager.getAllMatchingWifiConfigs(scanResult).size());
    984     }
    985 
    986     /**
    987      * Verify that an empty list will be returned when retrieving OSU providers for an AP with
    988      * null scan result.
    989      *
    990      * @throws Exception
    991      */
    992     @Test
    993     public void getMatchingOsuProvidersForNullScanResult() throws Exception {
    994         assertTrue(mManager.getMatchingOsuProviders(null).isEmpty());
    995     }
    996 
    997     /**
    998      * Verify that an empty list will be returned when retrieving OSU providers for an AP with
    999      * invalid BSSID.
   1000      *
   1001      * @throws Exception
   1002      */
   1003     @Test
   1004     public void getMatchingOsuProvidersForInvalidBSSID() throws Exception {
   1005         ScanResult scanResult = createTestScanResult();
   1006         scanResult.BSSID = "asdfdasfas";
   1007         assertTrue(mManager.getMatchingOsuProviders(scanResult).isEmpty());
   1008     }
   1009 
   1010     /**
   1011      * Verify that an empty list will be returned when retrieving OSU providers for a
   1012      * non-Passpoint AP.
   1013      *
   1014      * @throws Exception
   1015      */
   1016     @Test
   1017     public void getMatchingOsuProvidersForNonPasspointAP() throws Exception {
   1018         ScanResult scanResult = createTestScanResult();
   1019         scanResult.flags = 0;
   1020         assertTrue(mManager.getMatchingOsuProviders(scanResult).isEmpty());
   1021     }
   1022 
   1023     /**
   1024      * Verify that an empty list will be returned when no match is found from the ANQP cache.
   1025      *
   1026      * @throws Exception
   1027      */
   1028     @Test
   1029     public void getMatchingOsuProviderWithNoMatch() throws Exception {
   1030         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
   1031         assertTrue(mManager.getMatchingOsuProviders(createTestScanResult()).isEmpty());
   1032     }
   1033 
   1034     /**
   1035      * Verify that an expected provider list will be returned when a match is found from
   1036      * the ANQP cache.
   1037      *
   1038      * @throws Exception
   1039      */
   1040     @Test
   1041     public void getMatchingOsuProvidersWithMatch() throws Exception {
   1042         // Test data.
   1043         WifiSsid osuSsid = WifiSsid.createFromAsciiEncoded("Test SSID");
   1044         String friendlyName = "Test Provider";
   1045         String serviceDescription = "Dummy Service";
   1046         Uri serverUri = Uri.parse("https://test.com");
   1047         String nai = "access.test.com";
   1048         List<Integer> methodList = Arrays.asList(1);
   1049         List<I18Name> friendlyNames = Arrays.asList(
   1050                 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, friendlyName));
   1051         List<I18Name> serviceDescriptions = Arrays.asList(
   1052                 new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, serviceDescription));
   1053 
   1054         // Setup OSU providers ANQP element.
   1055         List<OsuProviderInfo> providerInfoList = new ArrayList<>();
   1056         providerInfoList.add(new OsuProviderInfo(
   1057                 friendlyNames, serverUri, methodList, null, nai, serviceDescriptions));
   1058         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
   1059         anqpElementMap.put(ANQPElementType.HSOSUProviders,
   1060                 new HSOsuProvidersElement(osuSsid, providerInfoList));
   1061         ANQPData entry = new ANQPData(mClock, anqpElementMap);
   1062 
   1063         // Setup expectation.
   1064         OsuProvider provider = new OsuProvider(
   1065                 osuSsid, friendlyName, serviceDescription, serverUri, nai, methodList, null);
   1066         List<OsuProvider> expectedList = new ArrayList<>();
   1067         expectedList.add(provider);
   1068 
   1069         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
   1070         assertEquals(expectedList, mManager.getMatchingOsuProviders(createTestScanResult()));
   1071     }
   1072 
   1073     /**
   1074      * Verify that the provider list maintained by the PasspointManager after the list is updated
   1075      * in the data source.
   1076      *
   1077      * @throws Exception
   1078      */
   1079     @Test
   1080     public void verifyProvidersAfterDataSourceUpdate() throws Exception {
   1081         // Update the provider list in the data source.
   1082         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
   1083         PasspointProvider provider = createMockProvider(config);
   1084         List<PasspointProvider> providers = new ArrayList<>();
   1085         providers.add(provider);
   1086         mDataSource.setProviders(providers);
   1087 
   1088         // Verify the providers maintained by PasspointManager.
   1089         assertEquals(1, mManager.getProviderConfigs().size());
   1090         assertEquals(config, mManager.getProviderConfigs().get(0));
   1091     }
   1092 
   1093     /**
   1094      * Verify that the provider index used by PasspointManager is updated after it is updated in
   1095      * the data source.
   1096      *
   1097      * @throws Exception
   1098      */
   1099     @Test
   1100     public void verifyProviderIndexAfterDataSourceUpdate() throws Exception {
   1101         long providerIndex = 9;
   1102         mDataSource.setProviderIndex(providerIndex);
   1103         assertEquals(providerIndex, mDataSource.getProviderIndex());
   1104 
   1105         // Add a provider.
   1106         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN);
   1107         PasspointProvider provider = createMockProvider(config);
   1108         // Verify the provider ID used to create the new provider.
   1109         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
   1110                 eq(mSimAccessor), eq(providerIndex), eq(TEST_CREATOR_UID))).thenReturn(provider);
   1111         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID));
   1112         verifyInstalledConfig(config);
   1113         verify(mWifiConfigManager).saveToStore(true);
   1114         reset(mWifiConfigManager);
   1115     }
   1116 
   1117     /**
   1118      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
   1119      * adding a legacy Passpoint configuration containing a valid user credential.
   1120      *
   1121      * @throws Exception
   1122      */
   1123     @Test
   1124     public void addLegacyPasspointConfigWithUserCredential() throws Exception {
   1125         // Test data.
   1126         String fqdn = "test.com";
   1127         String friendlyName = "Friendly Name";
   1128         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1129         String realm = "realm.com";
   1130         String username = "username";
   1131         String password = "password";
   1132         byte[] base64EncodedPw =
   1133                 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
   1134         String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
   1135         String caCertificateAlias = "CaCert";
   1136 
   1137         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1138         WifiConfiguration wifiConfig = new WifiConfiguration();
   1139         wifiConfig.FQDN = fqdn;
   1140         wifiConfig.providerFriendlyName = friendlyName;
   1141         wifiConfig.roamingConsortiumIds = rcOIs;
   1142         wifiConfig.enterpriseConfig.setIdentity(username);
   1143         wifiConfig.enterpriseConfig.setPassword(password);
   1144         wifiConfig.enterpriseConfig.setRealm(realm);
   1145         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
   1146         wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
   1147         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
   1148 
   1149         // Setup expected {@link PasspointConfiguration}
   1150         PasspointConfiguration passpointConfig = new PasspointConfiguration();
   1151         HomeSp homeSp = new HomeSp();
   1152         homeSp.setFqdn(fqdn);
   1153         homeSp.setFriendlyName(friendlyName);
   1154         homeSp.setRoamingConsortiumOis(rcOIs);
   1155         passpointConfig.setHomeSp(homeSp);
   1156         Credential credential = new Credential();
   1157         Credential.UserCredential userCredential = new Credential.UserCredential();
   1158         userCredential.setUsername(username);
   1159         userCredential.setPassword(encodedPasswordStr);
   1160         userCredential.setEapType(EAPConstants.EAP_TTLS);
   1161         userCredential.setNonEapInnerMethod("PAP");
   1162         credential.setUserCredential(userCredential);
   1163         credential.setRealm(realm);
   1164         passpointConfig.setCredential(credential);
   1165 
   1166         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1167         verifyInstalledConfig(passpointConfig);
   1168     }
   1169 
   1170     /**
   1171      * Verify that adding a legacy Passpoint configuration containing user credential will
   1172      * fail when client certificate is not provided.
   1173      *
   1174      * @throws Exception
   1175      */
   1176     @Test
   1177     public void addLegacyPasspointConfigWithUserCredentialWithoutCaCert() throws Exception {
   1178         // Test data.
   1179         String fqdn = "test.com";
   1180         String friendlyName = "Friendly Name";
   1181         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1182         String realm = "realm.com";
   1183         String username = "username";
   1184         String password = "password";
   1185         byte[] base64EncodedPw =
   1186                 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
   1187         String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
   1188 
   1189         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1190         WifiConfiguration wifiConfig = new WifiConfiguration();
   1191         wifiConfig.FQDN = fqdn;
   1192         wifiConfig.providerFriendlyName = friendlyName;
   1193         wifiConfig.roamingConsortiumIds = rcOIs;
   1194         wifiConfig.enterpriseConfig.setIdentity(username);
   1195         wifiConfig.enterpriseConfig.setPassword(password);
   1196         wifiConfig.enterpriseConfig.setRealm(realm);
   1197         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
   1198         wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
   1199 
   1200         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1201     }
   1202 
   1203     /**
   1204      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
   1205      * adding a legacy Passpoint configuration containing a valid SIM credential.
   1206      *
   1207      * @throws Exception
   1208      */
   1209     @Test
   1210     public void addLegacyPasspointConfigWithSimCredential() throws Exception {
   1211         // Test data.
   1212         String fqdn = "test.com";
   1213         String friendlyName = "Friendly Name";
   1214         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1215         String realm = "realm.com";
   1216         String imsi = "1234";
   1217 
   1218         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1219         WifiConfiguration wifiConfig = new WifiConfiguration();
   1220         wifiConfig.FQDN = fqdn;
   1221         wifiConfig.providerFriendlyName = friendlyName;
   1222         wifiConfig.roamingConsortiumIds = rcOIs;
   1223         wifiConfig.enterpriseConfig.setRealm(realm);
   1224         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
   1225         wifiConfig.enterpriseConfig.setPlmn(imsi);
   1226 
   1227         // Setup expected {@link PasspointConfiguration}
   1228         PasspointConfiguration passpointConfig = new PasspointConfiguration();
   1229         HomeSp homeSp = new HomeSp();
   1230         homeSp.setFqdn(fqdn);
   1231         homeSp.setFriendlyName(friendlyName);
   1232         homeSp.setRoamingConsortiumOis(rcOIs);
   1233         passpointConfig.setHomeSp(homeSp);
   1234         Credential credential = new Credential();
   1235         Credential.SimCredential simCredential = new Credential.SimCredential();
   1236         simCredential.setEapType(EAPConstants.EAP_SIM);
   1237         simCredential.setImsi(imsi);
   1238         credential.setSimCredential(simCredential);
   1239         credential.setRealm(realm);
   1240         passpointConfig.setCredential(credential);
   1241 
   1242         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1243         verifyInstalledConfig(passpointConfig);
   1244     }
   1245 
   1246     /**
   1247      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
   1248      * adding a legacy Passpoint configuration containing a valid certificate credential.
   1249      *
   1250      * @throws Exception
   1251      */
   1252     @Test
   1253     public void addLegacyPasspointConfigWithCertCredential() throws Exception {
   1254         // Test data.
   1255         String fqdn = "test.com";
   1256         String friendlyName = "Friendly Name";
   1257         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1258         String realm = "realm.com";
   1259         String caCertificateAlias = "CaCert";
   1260         String clientCertificateAlias = "ClientCert";
   1261 
   1262         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1263         WifiConfiguration wifiConfig = new WifiConfiguration();
   1264         wifiConfig.FQDN = fqdn;
   1265         wifiConfig.providerFriendlyName = friendlyName;
   1266         wifiConfig.roamingConsortiumIds = rcOIs;
   1267         wifiConfig.enterpriseConfig.setRealm(realm);
   1268         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
   1269         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
   1270         wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
   1271 
   1272         // Setup expected {@link PasspointConfiguration}
   1273         PasspointConfiguration passpointConfig = new PasspointConfiguration();
   1274         HomeSp homeSp = new HomeSp();
   1275         homeSp.setFqdn(fqdn);
   1276         homeSp.setFriendlyName(friendlyName);
   1277         homeSp.setRoamingConsortiumOis(rcOIs);
   1278         passpointConfig.setHomeSp(homeSp);
   1279         Credential credential = new Credential();
   1280         Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
   1281         certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
   1282         credential.setCertCredential(certCredential);
   1283         credential.setRealm(realm);
   1284         passpointConfig.setCredential(credential);
   1285 
   1286         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1287         verifyInstalledConfig(passpointConfig);
   1288     }
   1289 
   1290     /**
   1291      * Verify that adding a legacy Passpoint configuration containing certificate credential will
   1292      * fail when CA certificate is not provided.
   1293      *
   1294      * @throws Exception
   1295      */
   1296     @Test
   1297     public void addLegacyPasspointConfigWithCertCredentialWithoutCaCert() throws Exception {
   1298         // Test data.
   1299         String fqdn = "test.com";
   1300         String friendlyName = "Friendly Name";
   1301         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1302         String realm = "realm.com";
   1303         String clientCertificateAlias = "ClientCert";
   1304 
   1305         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1306         WifiConfiguration wifiConfig = new WifiConfiguration();
   1307         wifiConfig.FQDN = fqdn;
   1308         wifiConfig.providerFriendlyName = friendlyName;
   1309         wifiConfig.roamingConsortiumIds = rcOIs;
   1310         wifiConfig.enterpriseConfig.setRealm(realm);
   1311         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
   1312         wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
   1313 
   1314         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1315     }
   1316 
   1317     /**
   1318      * Verify that adding a legacy Passpoint configuration containing certificate credential will
   1319      * fail when client certificate is not provided.
   1320      *
   1321      * @throws Exception
   1322      */
   1323     @Test
   1324     public void addLegacyPasspointConfigWithCertCredentialWithoutClientCert() throws Exception {
   1325         // Test data.
   1326         String fqdn = "test.com";
   1327         String friendlyName = "Friendly Name";
   1328         long[] rcOIs = new long[] {0x1234L, 0x2345L};
   1329         String realm = "realm.com";
   1330         String caCertificateAlias = "CaCert";
   1331 
   1332         // Setup WifiConfiguration for legacy Passpoint configuraiton.
   1333         WifiConfiguration wifiConfig = new WifiConfiguration();
   1334         wifiConfig.FQDN = fqdn;
   1335         wifiConfig.providerFriendlyName = friendlyName;
   1336         wifiConfig.roamingConsortiumIds = rcOIs;
   1337         wifiConfig.enterpriseConfig.setRealm(realm);
   1338         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
   1339         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
   1340 
   1341         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
   1342     }
   1343 
   1344     /**
   1345      * Verify that the provider's "hasEverConnected" flag will be set to true and the associated
   1346      * metric is updated after the provider was used to successfully connect to a Passpoint
   1347      * network for the first time.
   1348      *
   1349      * @throws Exception
   1350      */
   1351     @Test
   1352     public void providerNetworkConnectedFirstTime() throws Exception {
   1353         PasspointProvider provider = addTestProvider(TEST_FQDN);
   1354         when(provider.getHasEverConnected()).thenReturn(false);
   1355         mManager.onPasspointNetworkConnected(TEST_FQDN);
   1356         verify(provider).setHasEverConnected(eq(true));
   1357     }
   1358 
   1359     /**
   1360      * Verify that the provider's "hasEverConnected" flag the associated metric is not updated
   1361      * after the provider was used to successfully connect to a Passpoint network for non-first
   1362      * time.
   1363      *
   1364      * @throws Exception
   1365      */
   1366     @Test
   1367     public void providerNetworkConnectedNotFirstTime() throws Exception {
   1368         PasspointProvider provider = addTestProvider(TEST_FQDN);
   1369         when(provider.getHasEverConnected()).thenReturn(true);
   1370         mManager.onPasspointNetworkConnected(TEST_FQDN);
   1371         verify(provider, never()).setHasEverConnected(anyBoolean());
   1372     }
   1373 
   1374     /**
   1375      * Verify that the expected Passpoint metrics are updated when
   1376      * {@link PasspointManager#updateMetrics} is invoked.
   1377      *
   1378      * @throws Exception
   1379      */
   1380     @Test
   1381     public void updateMetrics() throws Exception {
   1382         PasspointProvider provider = addTestProvider(TEST_FQDN);
   1383 
   1384         // Provider have not provided a successful network connection.
   1385         int expectedInstalledProviders = 1;
   1386         int expectedConnectedProviders = 0;
   1387         when(provider.getHasEverConnected()).thenReturn(false);
   1388         mManager.updateMetrics();
   1389         verify(mWifiMetrics).updateSavedPasspointProfiles(
   1390                 eq(expectedInstalledProviders), eq(expectedConnectedProviders));
   1391         reset(provider);
   1392         reset(mWifiMetrics);
   1393 
   1394         // Provider have provided a successful network connection.
   1395         expectedConnectedProviders = 1;
   1396         when(provider.getHasEverConnected()).thenReturn(true);
   1397         mManager.updateMetrics();
   1398         verify(mWifiMetrics).updateSavedPasspointProfiles(
   1399                 eq(expectedInstalledProviders), eq(expectedConnectedProviders));
   1400     }
   1401     /**
   1402      * Verify Passpoint Manager's provisioning APIs by invoking methods in PasspointProvisioner for
   1403      * initiailization and provisioning a provider.
   1404      */
   1405     @Test
   1406     public void verifyPasspointProvisioner() {
   1407         mManager.initializeProvisioner(mLooper.getLooper());
   1408         verify(mPasspointProvisioner).init(any(Looper.class));
   1409         when(mPasspointProvisioner.startSubscriptionProvisioning(anyInt(), any(OsuProvider.class),
   1410                 any(IProvisioningCallback.class))).thenReturn(true);
   1411         OsuProvider osuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
   1412         assertEquals(true,
   1413                 mManager.startSubscriptionProvisioning(TEST_UID, osuProvider, mCallback));
   1414     }
   1415 }
   1416