1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi.hotspot2;
18 
19 import static android.app.AppOpsManager.MODE_IGNORED;
20 import static android.app.AppOpsManager.OPSTR_CHANGE_WIFI_STATE;
21 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
22 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
23 
24 import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_EAP;
25 
26 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertFalse;
29 import static org.junit.Assert.assertNotNull;
30 import static org.junit.Assert.assertThat;
31 import static org.junit.Assert.assertTrue;
32 import static org.mockito.ArgumentMatchers.argThat;
33 import static org.mockito.ArgumentMatchers.isNull;
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.eq;
40 import static org.mockito.Mockito.lenient;
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.spy;
45 import static org.mockito.Mockito.times;
46 import static org.mockito.Mockito.verify;
47 import static org.mockito.Mockito.when;
48 import static org.mockito.MockitoAnnotations.initMocks;
49 
50 import android.app.AppOpsManager;
51 import android.content.Context;
52 import android.content.Intent;
53 import android.net.Uri;
54 import android.net.wifi.EAPConstants;
55 import android.net.wifi.ScanResult;
56 import android.net.wifi.WifiConfiguration;
57 import android.net.wifi.WifiEnterpriseConfig;
58 import android.net.wifi.WifiManager;
59 import android.net.wifi.WifiSsid;
60 import android.net.wifi.hotspot2.IProvisioningCallback;
61 import android.net.wifi.hotspot2.OsuProvider;
62 import android.net.wifi.hotspot2.PasspointConfiguration;
63 import android.net.wifi.hotspot2.pps.Credential;
64 import android.net.wifi.hotspot2.pps.HomeSp;
65 import android.os.Handler;
66 import android.os.Looper;
67 import android.os.UserHandle;
68 import android.os.test.TestLooper;
69 import android.telephony.SubscriptionInfo;
70 import android.telephony.SubscriptionManager;
71 import android.telephony.TelephonyManager;
72 import android.util.Base64;
73 import android.util.Pair;
74 
75 import androidx.test.filters.SmallTest;
76 
77 import com.android.server.wifi.ClientModeImpl;
78 import com.android.server.wifi.Clock;
79 import com.android.server.wifi.FakeKeys;
80 import com.android.server.wifi.FrameworkFacade;
81 import com.android.server.wifi.NetworkUpdateResult;
82 import com.android.server.wifi.WifiBaseTest;
83 import com.android.server.wifi.WifiCarrierInfoManager;
84 import com.android.server.wifi.WifiConfigManager;
85 import com.android.server.wifi.WifiConfigStore;
86 import com.android.server.wifi.WifiConfigurationTestUtil;
87 import com.android.server.wifi.WifiContext;
88 import com.android.server.wifi.WifiInjector;
89 import com.android.server.wifi.WifiKeyStore;
90 import com.android.server.wifi.WifiMetrics;
91 import com.android.server.wifi.WifiNative;
92 import com.android.server.wifi.WifiNetworkSuggestionsManager;
93 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
94 import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
95 import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
96 import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
97 import com.android.server.wifi.hotspot2.anqp.I18Name;
98 import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
99 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
100 import com.android.server.wifi.util.InformationElementUtil;
101 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
102 
103 import org.junit.Before;
104 import org.junit.Test;
105 import org.mockito.ArgumentCaptor;
106 import org.mockito.Mock;
107 import org.mockito.MockitoSession;
108 
109 import java.nio.charset.StandardCharsets;
110 import java.security.KeyStore;
111 import java.security.cert.Certificate;
112 import java.security.cert.X509Certificate;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.Collections;
116 import java.util.HashMap;
117 import java.util.HashSet;
118 import java.util.List;
119 import java.util.Locale;
120 import java.util.Map;
121 import java.util.Set;
122 
123 /**
124  * Unit tests for {@link PasspointManager}.
125  */
126 @SmallTest
127 public class PasspointManagerTest extends WifiBaseTest {
128     private static final long BSSID = 0x112233445566L;
129     private static final String TEST_PACKAGE = "com.android.test";
130     private static final String TEST_PACKAGE1 = "com.android.test1";
131     private static final String TEST_FQDN = "test1.test.com";
132     private static final String TEST_FQDN2 = "test2.test.com";
133     private static final String TEST_FRIENDLY_NAME = "friendly name";
134     private static final String TEST_FRIENDLY_NAME2 = "second friendly name";
135     private static final String TEST_REALM = "realm.test.com";
136     private static final String TEST_REALM2 = "realm.test2.com";
137     private static final String TEST_REALM3 = "realm.test3.com";
138     private static final String TEST_IMSI = "123456*";
139     private static final String FULL_IMSI = "123456789123456";
140     private static final int TEST_CARRIER_ID = 10;
141     private static final int TEST_SUBID = 1;
142 
143     private static final long TEST_BSSID = 0x112233445566L;
144     private static final String TEST_SSID = "TestSSID";
145     private static final String TEST_BSSID_STRING = "11:22:33:44:55:66";
146     private static final String TEST_SSID2 = "TestSSID2";
147     private static final String TEST_BSSID_STRING2 = "11:22:33:44:55:77";
148     private static final String TEST_SSID3 = "TestSSID3";
149     private static final String TEST_BSSID_STRING3 = "11:22:33:44:55:88";
150     private static final String TEST_MCC_MNC = "123456";
151     private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org",
152             TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3));
153 
154     private static final long TEST_HESSID = 0x5678L;
155     private static final int TEST_ANQP_DOMAIN_ID = 0;
156     private static final int TEST_ANQP_DOMAIN_ID2 = 1;
157     private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey(
158             TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID);
159     private static final ANQPNetworkKey TEST_ANQP_KEY2 = ANQPNetworkKey.buildKey(
160             TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID2);
161     private static final int TEST_CREATOR_UID = 1234;
162     private static final int TEST_CREATOR_UID1 = 1235;
163     private static final int TEST_UID = 1500;
164     private static final int TEST_NETWORK_ID = 2;
165 
166     @Mock Context mContext;
167     @Mock WifiNative mWifiNative;
168     @Mock WifiKeyStore mWifiKeyStore;
169     @Mock Clock mClock;
170     @Mock PasspointObjectFactory mObjectFactory;
171     @Mock PasspointEventHandler.Callbacks mCallbacks;
172     @Mock AnqpCache mAnqpCache;
173     @Mock ANQPRequestManager mAnqpRequestManager;
174     @Mock WifiConfigManager mWifiConfigManager;
175     @Mock WifiConfigStore mWifiConfigStore;
176     PasspointConfigSharedStoreData.DataSource mSharedDataSource;
177     PasspointConfigUserStoreData.DataSource mUserDataSource;
178     @Mock WifiMetrics mWifiMetrics;
179     @Mock OsuNetworkConnection mOsuNetworkConnection;
180     @Mock OsuServerConnection mOsuServerConnection;
181     @Mock PasspointProvisioner mPasspointProvisioner;
182     @Mock IProvisioningCallback mCallback;
183     @Mock WfaKeyStore mWfaKeyStore;
184     @Mock KeyStore mKeyStore;
185     @Mock AppOpsManager mAppOpsManager;
186     @Mock WifiInjector mWifiInjector;
187     @Mock ClientModeImpl mClientModeImpl;
188     @Mock TelephonyManager mTelephonyManager;
189     @Mock SubscriptionManager mSubscriptionManager;
190     @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
191 
192     Handler mHandler;
193     TestLooper mLooper;
194     PasspointManager mManager;
195     ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor =
196             ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class);
197     WifiCarrierInfoManager mWifiCarrierInfoManager;
198 
199     /** Sets up test. */
200     @Before
setUp()201     public void setUp() throws Exception {
202         initMocks(this);
203         when(mObjectFactory.makeAnqpCache(mClock)).thenReturn(mAnqpCache);
204         when(mObjectFactory.makeANQPRequestManager(any(), eq(mClock)))
205                 .thenReturn(mAnqpRequestManager);
206         when(mObjectFactory.makeOsuNetworkConnection(any(Context.class)))
207                 .thenReturn(mOsuNetworkConnection);
208         when(mObjectFactory.makeOsuServerConnection())
209                 .thenReturn(mOsuServerConnection);
210         when(mObjectFactory.makeWfaKeyStore()).thenReturn(mWfaKeyStore);
211         when(mWfaKeyStore.get()).thenReturn(mKeyStore);
212         when(mObjectFactory.makePasspointProvisioner(any(Context.class), any(WifiNative.class),
213                 any(PasspointManager.class), any(WifiMetrics.class)))
214                 .thenReturn(mPasspointProvisioner);
215         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
216         when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
217         when(mWifiInjector.getWifiNetworkSuggestionsManager())
218                 .thenReturn(mWifiNetworkSuggestionsManager);
219         mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager,
220                 mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class),
221                 mock(WifiContext.class), mWifiConfigStore, mock(Handler.class), mWifiMetrics);
222         mLooper = new TestLooper();
223         mHandler = new Handler(mLooper.getLooper());
224         mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
225                 mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager,
226                 mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager);
227         ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks =
228                 ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class);
229         verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class),
230                                                          callbacks.capture());
231         ArgumentCaptor<PasspointConfigSharedStoreData.DataSource> sharedDataSource =
232                 ArgumentCaptor.forClass(PasspointConfigSharedStoreData.DataSource.class);
233         verify(mObjectFactory).makePasspointConfigSharedStoreData(sharedDataSource.capture());
234         ArgumentCaptor<PasspointConfigUserStoreData.DataSource> userDataSource =
235                 ArgumentCaptor.forClass(PasspointConfigUserStoreData.DataSource.class);
236         verify(mObjectFactory).makePasspointConfigUserStoreData(any(WifiKeyStore.class),
237                 any(WifiCarrierInfoManager.class), userDataSource.capture());
238         mCallbacks = callbacks.getValue();
239         mSharedDataSource = sharedDataSource.getValue();
240         mUserDataSource = userDataSource.getValue();
241         // SIM is absent
242         when(mSubscriptionManager.getActiveSubscriptionInfoList())
243                 .thenReturn(Collections.emptyList());
244     }
245 
246     /**
247      * Verify that the given Passpoint configuration matches the one that's added to
248      * the PasspointManager.
249      *
250      * @param expectedConfig The expected installed Passpoint configuration
251      */
verifyInstalledConfig(PasspointConfiguration expectedConfig)252     private void verifyInstalledConfig(PasspointConfiguration expectedConfig) {
253         List<PasspointConfiguration> installedConfigs =
254                 mManager.getProviderConfigs(TEST_CREATOR_UID, true);
255         assertEquals(1, installedConfigs.size());
256         assertEquals(expectedConfig, installedConfigs.get(0));
257     }
258 
createMockProvider(PasspointConfiguration config)259     private PasspointProvider createMockProvider(PasspointConfiguration config) {
260         WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1,
261                 TEST_UID, "\"PasspointTestSSID\"", true, true,
262                 config.getHomeSp().getFqdn(), TEST_FRIENDLY_NAME, SECURITY_EAP);
263         return createMockProvider(config, wifiConfig, false);
264     }
265 
266     /**
267      * Create a mock PasspointProvider with default expectations.
268      *
269      * @param config The configuration associated with the provider
270      * @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
271      */
createMockProvider( PasspointConfiguration config, WifiConfiguration wifiConfig, boolean isSuggestion)272     private PasspointProvider createMockProvider(
273             PasspointConfiguration config, WifiConfiguration wifiConfig, boolean isSuggestion) {
274         PasspointProvider provider = mock(PasspointProvider.class);
275         when(provider.installCertsAndKeys()).thenReturn(true);
276         lenient().when(provider.getConfig()).thenReturn(config);
277         lenient().when(provider.getWifiConfig()).thenReturn(wifiConfig);
278         lenient().when(provider.getCreatorUid()).thenReturn(TEST_CREATOR_UID);
279         lenient().when(provider.isFromSuggestion()).thenReturn(isSuggestion);
280         lenient().when(provider.isAutojoinEnabled()).thenReturn(true);
281         return provider;
282     }
283 
284     /**
285      * Helper function for creating a test configuration with user credential.
286      *
287      * @return {@link PasspointConfiguration}
288      */
createTestConfigWithUserCredential(String fqdn, String friendlyName)289     private PasspointConfiguration createTestConfigWithUserCredential(String fqdn,
290             String friendlyName) {
291         return createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, TEST_REALM);
292     }
293 
294         /**
295          * Helper function for creating a test configuration with user credential
296          * and a unique realm.
297          *
298          * @return {@link PasspointConfiguration}
299          */
createTestConfigWithUserCredentialAndRealm(String fqdn, String friendlyName, String realm)300     private PasspointConfiguration createTestConfigWithUserCredentialAndRealm(String fqdn,
301             String friendlyName, String realm) {
302         PasspointConfiguration config = new PasspointConfiguration();
303         HomeSp homeSp = new HomeSp();
304         homeSp.setFqdn(fqdn);
305         homeSp.setFriendlyName(friendlyName);
306         config.setHomeSp(homeSp);
307         Map<String, String> friendlyNames = new HashMap<>();
308         friendlyNames.put("en", friendlyName);
309         friendlyNames.put("kr", friendlyName + 1);
310         friendlyNames.put("jp", friendlyName + 2);
311         config.setServiceFriendlyNames(friendlyNames);
312         Credential credential = new Credential();
313         credential.setRealm(realm != null ? realm : TEST_REALM);
314         credential.setCaCertificate(FakeKeys.CA_CERT0);
315         Credential.UserCredential userCredential = new Credential.UserCredential();
316         userCredential.setUsername("username");
317         userCredential.setPassword("password");
318         userCredential.setEapType(EAPConstants.EAP_TTLS);
319         userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAP);
320         credential.setUserCredential(userCredential);
321         config.setCredential(credential);
322         return config;
323     }
324 
325     /**
326      * Helper function for creating a test configuration with SIM credential.
327      *
328      * @return {@link PasspointConfiguration}
329      */
createTestConfigWithSimCredential(String fqdn, String imsi, String realm)330     private PasspointConfiguration createTestConfigWithSimCredential(String fqdn, String imsi,
331             String realm) {
332         PasspointConfiguration config = new PasspointConfiguration();
333         HomeSp homeSp = new HomeSp();
334         homeSp.setFqdn(fqdn);
335         homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
336         config.setHomeSp(homeSp);
337         Credential credential = new Credential();
338         credential.setRealm(TEST_REALM);
339         Credential.SimCredential simCredential = new Credential.SimCredential();
340         simCredential.setImsi(imsi);
341         simCredential.setEapType(EAPConstants.EAP_SIM);
342         credential.setSimCredential(simCredential);
343         config.setCredential(credential);
344         return config;
345     }
346 
addTestProvider(String fqdn, String friendlyName, String packageName, boolean isSuggestion, String realm)347     private PasspointProvider addTestProvider(String fqdn, String friendlyName,
348             String packageName, boolean isSuggestion, String realm) {
349         WifiConfiguration wifiConfig = WifiConfigurationTestUtil.generateWifiConfig(-1, TEST_UID,
350                 "\"PasspointTestSSID\"", true, true,
351                 fqdn, friendlyName, SECURITY_EAP);
352 
353         return addTestProvider(fqdn, friendlyName, packageName, wifiConfig, isSuggestion, realm);
354     }
355 
356     /**
357      * Helper function for adding a test provider to the manager.  Return the mock
358      * provider that's added to the manager.
359      *
360      * @return {@link PasspointProvider}
361      */
addTestProvider(String fqdn, String friendlyName, String packageName, WifiConfiguration wifiConfig, boolean isSuggestion, String realm)362     private PasspointProvider addTestProvider(String fqdn, String friendlyName,
363             String packageName, WifiConfiguration wifiConfig, boolean isSuggestion, String realm) {
364         PasspointConfiguration config =
365                 createTestConfigWithUserCredentialAndRealm(fqdn, friendlyName, realm);
366         wifiConfig.setPasspointUniqueId(config.getUniqueId());
367         PasspointProvider provider = createMockProvider(config, wifiConfig, isSuggestion);
368         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
369                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
370                 eq(isSuggestion))).thenReturn(provider);
371         when(provider.getPackageName()).thenReturn(packageName);
372         assertTrue(mManager.addOrUpdateProvider(
373                 config, TEST_CREATOR_UID, TEST_PACKAGE, isSuggestion, true));
374         return provider;
375     }
376 
377     /**
378      * Helper function for creating a ScanResult for testing.
379      *
380      * @return {@link ScanResult}
381      */
createTestScanResult()382     private ScanResult createTestScanResult() {
383         ScanResult scanResult = new ScanResult();
384         scanResult.SSID = TEST_SSID;
385         scanResult.BSSID = TEST_BSSID_STRING;
386         scanResult.hessid = TEST_HESSID;
387         scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID;
388         scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
389         return scanResult;
390     }
391 
392     /**
393      * Helper function for creating a ScanResult for testing.
394      *
395      * @return {@link ScanResult}
396      */
createTestScanResults()397     private List<ScanResult> createTestScanResults() {
398         List<ScanResult> scanResults = new ArrayList<>();
399 
400         // Passpoint AP
401         ScanResult scanResult = new ScanResult();
402         scanResult.SSID = TEST_SSID;
403         scanResult.BSSID = TEST_BSSID_STRING;
404         scanResult.hessid = TEST_HESSID;
405         scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
406         scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID2;
407         scanResults.add(scanResult);
408 
409         // Non-Passpoint AP
410         ScanResult scanResult2 = new ScanResult();
411         scanResult2.SSID = TEST_SSID2;
412         scanResult2.BSSID = TEST_BSSID_STRING2;
413         scanResult2.hessid = TEST_HESSID;
414         scanResult2.flags = 0;
415         scanResults.add(scanResult2);
416 
417         // Passpoint AP
418         ScanResult scanResult3 = new ScanResult();
419         scanResult3.SSID = TEST_SSID3;
420         scanResult3.BSSID = TEST_BSSID_STRING3;
421         scanResult3.hessid = TEST_HESSID;
422         scanResult3.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
423         scanResult3.anqpDomainId = TEST_ANQP_DOMAIN_ID2;
424         scanResults.add(scanResult3);
425 
426         return scanResults;
427     }
428 
429     /**
430      * Verify that the ANQP elements will be added to the ANQP cache on receiving a successful
431      * response.
432      *
433      * @throws Exception
434      */
435     @Test
anqpResponseSuccess()436     public void anqpResponseSuccess() throws Exception {
437         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
438         anqpElementMap.put(ANQPElementType.ANQPDomName,
439                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
440 
441         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY);
442         mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
443         verify(mAnqpCache).addEntry(TEST_ANQP_KEY, anqpElementMap);
444         verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
445                 any(String.class));
446     }
447 
448     /**
449      * Verify that no ANQP elements will be added to the ANQP cache on receiving a successful
450      * response for a request that's not sent by us.
451      *
452      * @throws Exception
453      */
454     @Test
anqpResponseSuccessWithUnknownRequest()455     public void anqpResponseSuccessWithUnknownRequest() throws Exception {
456         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
457         anqpElementMap.put(ANQPElementType.ANQPDomName,
458                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
459 
460         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(null);
461         mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap);
462         verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
463     }
464 
465     /**
466      * Verify that no ANQP elements will be added to the ANQP cache on receiving a failure response.
467      *
468      * @throws Exception
469      */
470     @Test
anqpResponseFailure()471     public void anqpResponseFailure() throws Exception {
472         when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY);
473         mCallbacks.onANQPResponse(TEST_BSSID, null);
474         verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap());
475 
476     }
477 
478     /**
479      * Verify that adding a provider with a null configuration will fail.
480      *
481      * @throws Exception
482      */
483     @Test
addProviderWithNullConfig()484     public void addProviderWithNullConfig() throws Exception {
485         assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE,
486                 false, true));
487         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
488         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
489     }
490 
491     /**
492      * Verify that adding a provider with a empty configuration will fail.
493      *
494      * @throws Exception
495      */
496     @Test
addProviderWithEmptyConfig()497     public void addProviderWithEmptyConfig() throws Exception {
498         assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID,
499                 TEST_PACKAGE, false, true));
500         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
501         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
502     }
503 
504     /**
505      * Verify taht adding a provider with an invalid credential will fail (using EAP-TLS
506      * for user credential).
507      *
508      * @throws Exception
509      */
510     @Test
addProviderWithInvalidCredential()511     public void addProviderWithInvalidCredential() throws Exception {
512         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
513                 TEST_FRIENDLY_NAME);
514         // EAP-TLS not allowed for user credential.
515         config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS);
516         assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
517                 false, true));
518         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
519         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
520     }
521 
522     /**
523      * Verify that adding a user saved provider with a valid configuration and user credential will
524      * succeed.
525      *
526      * @throws Exception
527      */
addRemoveSavedProviderWithValidUserCredential(boolean useFqdn)528     private void addRemoveSavedProviderWithValidUserCredential(boolean useFqdn) throws Exception {
529         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
530                 TEST_FRIENDLY_NAME);
531         PasspointProvider provider = createMockProvider(config);
532         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
533         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
534                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
535                 eq(false))).thenReturn(provider);
536         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
537                 false, true));
538         verifyInstalledConfig(config);
539         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
540         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
541         verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE),
542                 any(AppOpsManager.OnOpChangedListener.class));
543         reset(mWifiMetrics);
544         reset(mWifiConfigManager);
545 
546         // Verify content in the data source.
547         List<PasspointProvider> providers = mUserDataSource.getProviders();
548         assertEquals(1, providers.size());
549         assertEquals(config, providers.get(0).getConfig());
550 
551         // Verify calling |enableAutoJoin|, |enableMacRandomization|, and |setMeteredOverride|
552         verifyEnableAutojoin(providers.get(0), useFqdn);
553         verifyEnableMacRandomization(providers.get(0));
554         verifySetMeteredOverride(providers.get(0));
555 
556         // Provider index start with 0, should be 1 after adding a provider.
557         assertEquals(1, mSharedDataSource.getProviderIndex());
558 
559         // Remove the provider as the creator app.
560         if (useFqdn) {
561             assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
562         } else {
563             assertTrue(
564                     mManager.removeProvider(TEST_CREATOR_UID, false, config.getUniqueId(), null));
565         }
566 
567         verify(provider).uninstallCertsAndKeys();
568         verify(mWifiConfigManager, times(3)).removePasspointConfiguredNetwork(
569                 provider.getWifiConfig().getKey());
570         /**
571          * 1 from |removeProvider| + 2 from |setAutojoinEnabled| + 2 from
572          * |enableMacRandomization| + 2 from |setMeteredOverride| = 7 calls to |saveToStore|
573          */
574         verify(mWifiConfigManager, times(7)).saveToStore(true);
575         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
576         verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
577         verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class));
578         assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
579 
580         // Verify content in the data source.
581         assertTrue(mUserDataSource.getProviders().isEmpty());
582         // Removing a provider should not change the provider index.
583         assertEquals(1, mSharedDataSource.getProviderIndex());
584     }
585 
586     /**
587      * Verify that adding a user saved provider with a valid configuration and user credential will
588      * succeed. Remove provider using FQDN as key.
589      *
590      * @throws Exception
591      */
592     @Test
addRemoveByFqdnSavedProviderWithValidUserCredential()593     public void addRemoveByFqdnSavedProviderWithValidUserCredential() throws Exception {
594         addRemoveSavedProviderWithValidUserCredential(true);
595     }
596 
597     /**
598      * Verify that adding a user saved provider with a valid configuration and user credential will
599      * succeed. Remove provider using unique identifier as key.
600      *
601      * @throws Exception
602      */
603     @Test
addRemoveByUniqueIdSavedProviderWithValidUserCredential()604     public void addRemoveByUniqueIdSavedProviderWithValidUserCredential() throws Exception {
605         addRemoveSavedProviderWithValidUserCredential(false);
606     }
607 
608     /**
609      * Verify enable/disable autojoin on a provider.
610      * @param provider a mock provider that is already added into the PasspointManager
611      */
verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn)612     private void verifyEnableAutojoin(PasspointProvider provider, boolean useFqdn) {
613         when(provider.setAutojoinEnabled(anyBoolean())).thenReturn(true);
614         if (useFqdn) {
615             assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(),
616                     false));
617             verify(provider).setAutojoinEnabled(false);
618             assertTrue(mManager.enableAutojoin(null, provider.getConfig().getHomeSp().getFqdn(),
619                     true));
620             verify(provider).setAutojoinEnabled(true);
621             assertFalse(mManager.enableAutojoin(null, provider.getConfig().getHomeSp()
622                     .getFqdn() + "-XXXX", true));
623         } else {
624             assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null,
625                     false));
626             verify(provider).setAutojoinEnabled(false);
627             assertTrue(mManager.enableAutojoin(provider.getConfig().getUniqueId(), null,
628                     true));
629             verify(provider).setAutojoinEnabled(true);
630             assertFalse(
631                     mManager.enableAutojoin(provider.getConfig().getHomeSp().getFqdn() + "-XXXX",
632                             null, true));
633         }
634         verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF,
635                 false, true);
636         verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON,
637                 false, true);
638     }
639 
640     /**
641      * Verify enable/disable mac randomization on a provider.
642      * @param provider a mock provider that is already added into the PasspointManager
643      */
verifyEnableMacRandomization(PasspointProvider provider)644     private void verifyEnableMacRandomization(PasspointProvider provider) {
645         when(provider.setMacRandomizationEnabled(anyBoolean())).thenReturn(true);
646         assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
647                 false));
648         verify(provider).setMacRandomizationEnabled(false);
649         verify(mWifiMetrics).logUserActionEvent(
650                 UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF, false, true);
651         assertTrue(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn(),
652                 true));
653         verify(mWifiConfigManager, times(2)).removePasspointConfiguredNetwork(
654                 provider.getWifiConfig().getKey());
655         verify(mWifiMetrics).logUserActionEvent(
656                 UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON, false, true);
657         verify(provider).setMacRandomizationEnabled(true);
658         assertFalse(mManager.enableMacRandomization(provider.getConfig().getHomeSp().getFqdn()
659                 + "-XXXX", false));
660     }
661 
verifySetMeteredOverride(PasspointProvider provider)662     private void verifySetMeteredOverride(PasspointProvider provider) {
663         when(provider.setMeteredOverride(anyInt())).thenReturn(true);
664         assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
665                 METERED_OVERRIDE_METERED));
666         verify(provider).setMeteredOverride(METERED_OVERRIDE_METERED);
667         verify(mWifiMetrics).logUserActionEvent(
668                 UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED, false, true);
669         assertTrue(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn(),
670                 METERED_OVERRIDE_NOT_METERED));
671         verify(provider).setMeteredOverride(METERED_OVERRIDE_NOT_METERED);
672         verify(mWifiMetrics).logUserActionEvent(
673                 UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED, false, true);
674         assertFalse(mManager.setMeteredOverride(provider.getConfig().getHomeSp().getFqdn()
675                 + "-XXXX", METERED_OVERRIDE_METERED));
676     }
677 
678     /**
679      * Verify that adding a user saved  provider with a valid configuration and SIM credential will
680      * succeed.
681      *
682      * @throws Exception
683      */
684     @Test
addRemoveSavedProviderWithValidSimCredential()685     public void addRemoveSavedProviderWithValidSimCredential() throws Exception {
686         PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
687                 TEST_REALM);
688         PasspointProvider provider = createMockProvider(config);
689         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
690                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
691                 eq(false))).thenReturn(provider);
692         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
693                 false, true));
694         verifyInstalledConfig(config);
695         verify(mWifiConfigManager).saveToStore(true);
696         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
697         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
698         reset(mWifiMetrics);
699         reset(mWifiConfigManager);
700 
701         // Verify content in the data source.
702         List<PasspointProvider> providers = mUserDataSource.getProviders();
703         assertEquals(1, providers.size());
704         assertEquals(config, providers.get(0).getConfig());
705         // Provider index start with 0, should be 1 after adding a provider.
706         assertEquals(1, mSharedDataSource.getProviderIndex());
707 
708         // Remove the provider as a privileged non-creator app.
709         assertTrue(mManager.removeProvider(TEST_UID, true, null, TEST_FQDN));
710         verify(provider).uninstallCertsAndKeys();
711         verify(mWifiConfigManager).removePasspointConfiguredNetwork(
712                 provider.getWifiConfig().getKey());
713         verify(mWifiConfigManager).saveToStore(true);
714         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
715         verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
716         assertTrue(mManager.getProviderConfigs(TEST_UID, true).isEmpty());
717 
718         // Verify content in the data source.
719         assertTrue(mUserDataSource.getProviders().isEmpty());
720         // Removing a provider should not change the provider index.
721         assertEquals(1, mSharedDataSource.getProviderIndex());
722     }
723 
724     /**
725      * Verify that if the passpoint profile has full IMSI, the carrier ID should be updated when
726      * the matched SIM card is present.
727      * @throws Exception
728      */
729     @Test
addProviderWithValidFullImsiOfSimCredential()730     public void addProviderWithValidFullImsiOfSimCredential() throws Exception {
731         PasspointConfiguration config =
732                 createTestConfigWithSimCredential(TEST_FQDN, FULL_IMSI, TEST_REALM);
733         X509Certificate[] certArr = new X509Certificate[] {FakeKeys.CA_CERT0};
734         config.getCredential().setCaCertificates(certArr);
735         SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
736         when(subInfo.getSubscriptionId()).thenReturn(TEST_SUBID);
737         when(subInfo.getCarrierId()).thenReturn(TEST_CARRIER_ID);
738         TelephonyManager specifiedTm = mock(TelephonyManager.class);
739         when(mTelephonyManager.createForSubscriptionId(eq(TEST_SUBID))).thenReturn(specifiedTm);
740         when(specifiedTm.getSubscriberId()).thenReturn(FULL_IMSI);
741         List<SubscriptionInfo> subInfoList = new ArrayList<SubscriptionInfo>() {{
742                 add(subInfo);
743             }};
744         when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfoList);
745         when(mWifiKeyStore.putCaCertInKeyStore(any(String.class), any(Certificate.class)))
746                 .thenReturn(true);
747         PasspointObjectFactory spyFactory = spy(new PasspointObjectFactory());
748         when(mWifiNetworkSuggestionsManager.isPasspointSuggestionSharedWithUser(any()))
749                 .thenReturn(true);
750         PasspointManager ut = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
751                 mWifiKeyStore, mClock, spyFactory, mWifiConfigManager,
752                 mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager);
753 
754         assertTrue(ut.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
755                 true, true));
756 
757         assertEquals(TEST_CARRIER_ID, config.getCarrierId());
758         List<String> passpointProfilesList = new ArrayList<String>(){{
759                 add(config.getUniqueId());
760             }};
761         assertEquals(TEST_CARRIER_ID,
762                 ut.getWifiConfigsForPasspointProfiles(passpointProfilesList).get(0).carrierId);
763 
764     }
765 
766     /**
767      * Verify that adding a user saved provider with the same base domain as the existing provider
768      * will succeed, and verify that the new provider with the new configuration is added.
769      *
770      * @throws Exception
771      */
772     @Test
addSavedProviderWithExistingConfig()773     public void addSavedProviderWithExistingConfig() throws Exception {
774         // Add a provider with the original configuration.
775         PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
776                 TEST_REALM);
777         PasspointProvider origProvider = createMockProvider(origConfig);
778         when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
779                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
780                 eq(false))).thenReturn(origProvider);
781         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
782                 false, true));
783         verifyInstalledConfig(origConfig);
784         verify(mWifiConfigManager).saveToStore(true);
785         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
786         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
787         reset(mWifiMetrics);
788         reset(mWifiConfigManager);
789 
790         // Verify data source content.
791         List<PasspointProvider> origProviders = mUserDataSource.getProviders();
792         assertEquals(1, origProviders.size());
793         assertEquals(origConfig, origProviders.get(0).getConfig());
794         assertEquals(1, mSharedDataSource.getProviderIndex());
795 
796         // Add same provider as existing suggestion provider
797         // This should be no WifiConfig deletion
798         WifiConfiguration origWifiConfig = origProvider.getWifiConfig();
799         when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getKey()))
800                 .thenReturn(origWifiConfig);
801         when(mWifiConfigManager.addOrUpdateNetwork(
802                 origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE))
803                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
804         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
805                 false, true));
806         verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
807                 origWifiConfig.getKey());
808         verify(mWifiConfigManager).addOrUpdateNetwork(
809                 argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE));
810         verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin);
811         verify(mWifiConfigManager).saveToStore(true);
812         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
813         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
814         assertEquals(2, mSharedDataSource.getProviderIndex());
815         reset(mWifiMetrics);
816         reset(mWifiConfigManager);
817 
818         // Add another provider with the same base domain as the existing provider.
819         // This should replace the existing provider with the new configuration.
820         PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
821                 TEST_FRIENDLY_NAME);
822         PasspointProvider newProvider = createMockProvider(newConfig);
823         when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
824                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
825                 eq(false))).thenReturn(newProvider);
826         when(mWifiConfigManager.getConfiguredNetwork(origProvider.getWifiConfig().getKey()))
827                 .thenReturn(origWifiConfig);
828         assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
829                 false, true));
830 
831         List<PasspointConfiguration> installedConfigs =
832                 mManager.getProviderConfigs(TEST_CREATOR_UID, true);
833         assertEquals(2, installedConfigs.size());
834         assertTrue(installedConfigs.contains(origConfig));
835         assertTrue(installedConfigs.contains(newConfig));
836 
837         verify(mWifiConfigManager).saveToStore(true);
838         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
839         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
840 
841         // Verify data source content.
842         List<PasspointProvider> newProviders = mUserDataSource.getProviders();
843         assertEquals(2, newProviders.size());
844         assertTrue(newConfig.equals(newProviders.get(0).getConfig())
845                 || newConfig.equals(newProviders.get(1).getConfig()));
846         assertEquals(3, mSharedDataSource.getProviderIndex());
847     }
848 
849     /**
850      * Verify that adding a provider will fail when failing to install certificates and
851      * key to the keystore.
852      *
853      * @throws Exception
854      */
855     @Test
addProviderOnKeyInstallationFailiure()856     public void addProviderOnKeyInstallationFailiure() throws Exception {
857         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
858                 TEST_FRIENDLY_NAME);
859         PasspointProvider provider = mock(PasspointProvider.class);
860         when(provider.installCertsAndKeys()).thenReturn(false);
861         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), eq(
862                 mWifiCarrierInfoManager),
863                 anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
864         assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
865                 false, true));
866         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
867         verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
868     }
869 
870     /**
871      * Verify that adding a provider with R1 configuration and a private self-signed CA certificate
872      * is installed correctly.
873      *
874      * @throws Exception
875      */
876     @Test
addProviderWithR1ConfigPrivateCaCert()877     public void addProviderWithR1ConfigPrivateCaCert() throws Exception {
878         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
879                 TEST_FRIENDLY_NAME);
880         PasspointProvider provider = createMockProvider(config);
881         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
882                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
883                 eq(false))).thenReturn(provider);
884         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
885                 false, true));
886         verifyInstalledConfig(config);
887         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
888         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
889     }
890 
891     /**
892      * Verify that adding a provider with R2 configuration will not perform CA certificate
893      * verification.
894      *
895      * @throws Exception
896      */
897     @Test
addProviderWithR2Config()898     public void addProviderWithR2Config() throws Exception {
899         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
900                 TEST_FRIENDLY_NAME);
901         config.setUpdateIdentifier(1);
902         PasspointProvider provider = createMockProvider(config);
903         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
904                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
905                 eq(false))).thenReturn(provider);
906         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
907                 false, true));
908         verifyInstalledConfig(config);
909         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
910         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
911     }
912 
913     /**
914      * Verify that removing a non-existing provider will fail.
915      *
916      * @throws Exception
917      */
918     @Test
removeNonExistingProvider()919     public void removeNonExistingProvider() throws Exception {
920         assertFalse(mManager.removeProvider(TEST_CREATOR_UID, true, null, TEST_FQDN));
921         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
922         verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
923     }
924 
925     /**
926      * Verify that a empty list will be returned when no providers are installed.
927      *
928      * @throws Exception
929      */
930     @Test
matchProviderWithNoProvidersInstalled()931     public void matchProviderWithNoProvidersInstalled() throws Exception {
932         assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
933     }
934 
935     /**
936      * Verify that a {code null} be returned when ANQP entry doesn't exist in the cache.
937      *
938      * @throws Exception
939      */
940     @Test
matchProviderWithAnqpCacheMissed()941     public void matchProviderWithAnqpCacheMissed() throws Exception {
942         // static mocking
943         MockitoSession session =
944                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
945                         InformationElementUtil.class).startMocking();
946         try {
947             addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
948 
949             when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
950             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
951             vsa.hsRelease = NetworkDetail.HSRelease.R1;
952             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
953             InformationElementUtil.RoamingConsortium roamingConsortium =
954                     new InformationElementUtil.RoamingConsortium();
955             roamingConsortium.anqpOICount = 0;
956             when(InformationElementUtil.getRoamingConsortiumIE(isNull()))
957                     .thenReturn(roamingConsortium);
958             assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
959             // Verify that a request for ANQP elements is initiated.
960             verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID),
961                     any(ANQPNetworkKey.class),
962                     anyBoolean(), any(NetworkDetail.HSRelease.class));
963         } finally {
964             session.finishMocking();
965         }
966     }
967 
968     /**
969      * Verify that the expected provider will be returned when a HomeProvider is matched.
970      *
971      * @throws Exception
972      */
973     @Test
matchProviderAsHomeProvider()974     public void matchProviderAsHomeProvider() throws Exception {
975         PasspointProvider provider =
976                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
977         ANQPData entry = new ANQPData(mClock, null);
978 
979         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
980         when(provider.match(anyMap(), any(RoamingConsortium.class)))
981             .thenReturn(PasspointMatch.HomeProvider);
982         List<Pair<PasspointProvider, PasspointMatch>> results =
983                 mManager.matchProvider(createTestScanResult());
984         Pair<PasspointProvider, PasspointMatch> result = results.get(0);
985         assertEquals(PasspointMatch.HomeProvider, result.second);
986         assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
987     }
988 
989     /**
990      * Verify that the expected provider will be returned when a RoamingProvider is matched.
991      *
992      * @throws Exception
993      */
994     @Test
matchProviderAsRoamingProvider()995     public void matchProviderAsRoamingProvider() throws Exception {
996         PasspointProvider provider =
997                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
998         ANQPData entry = new ANQPData(mClock, null);
999 
1000         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
1001         when(provider.match(anyMap(), any(RoamingConsortium.class)))
1002             .thenReturn(PasspointMatch.RoamingProvider);
1003         List<Pair<PasspointProvider, PasspointMatch>> results =
1004                 mManager.matchProvider(createTestScanResult());
1005         Pair<PasspointProvider, PasspointMatch> result = results.get(0);
1006         assertEquals(PasspointMatch.RoamingProvider, result.second);
1007         assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
1008     }
1009 
1010     /**
1011      * When multiple providers matched for a single scanResult, when there is any home provider
1012      * available, return all matched home provider. Otherwise return all roaming provider.
1013      */
1014     @Test
matchScanResultWithMultipleProviderAsHomeAndRoaming()1015     public void matchScanResultWithMultipleProviderAsHomeAndRoaming() {
1016         // Only add roaming providers.
1017         PasspointProvider roamingProvider1 =
1018                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1019         PasspointProvider roamingProvider2 =
1020                 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE1, false, null);
1021         ANQPData entry = new ANQPData(mClock, null);
1022         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
1023         when(roamingProvider1.match(anyMap(), any(RoamingConsortium.class)))
1024                 .thenReturn(PasspointMatch.RoamingProvider);
1025         when(roamingProvider2.match(anyMap(), any(RoamingConsortium.class)))
1026                 .thenReturn(PasspointMatch.RoamingProvider);
1027         List<Pair<PasspointProvider, PasspointMatch>> results =
1028                 mManager.matchProvider(createTestScanResult());
1029         // Return all matched roaming providers.
1030         assertEquals(2, results.size());
1031         for (Pair<PasspointProvider, PasspointMatch> result : results) {
1032             assertEquals(PasspointMatch.RoamingProvider, result.second);
1033         }
1034         // Add home providers.
1035         PasspointProvider homeProvider1 =
1036                 addTestProvider(TEST_FQDN + "home", TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1037         PasspointProvider homeProvider2 = addTestProvider(TEST_FQDN2 + "home", TEST_FRIENDLY_NAME2,
1038                 TEST_PACKAGE1, false, null);
1039         when(homeProvider1.match(anyMap(), any(RoamingConsortium.class)))
1040                 .thenReturn(PasspointMatch.HomeProvider);
1041         when(homeProvider2.match(anyMap(), any(RoamingConsortium.class)))
1042                 .thenReturn(PasspointMatch.HomeProvider);
1043         results = mManager.matchProvider(createTestScanResult());
1044         // When home providers are available, should return all home providers.
1045         assertEquals(2, results.size());
1046         for (Pair<PasspointProvider, PasspointMatch> result : results) {
1047             assertEquals(PasspointMatch.HomeProvider, result.second);
1048         }
1049     }
1050 
1051     /**
1052      * Verify that a {code null} will be returned when there is no matching provider.
1053      *
1054      * @throws Exception
1055      */
1056     @Test
matchProviderWithNoMatch()1057     public void matchProviderWithNoMatch() throws Exception {
1058         PasspointProvider provider =
1059                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1060         ANQPData entry = new ANQPData(mClock, null);
1061 
1062         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
1063         when(provider.match(anyMap(), any(RoamingConsortium.class)))
1064             .thenReturn(PasspointMatch.None);
1065         assertTrue(mManager.matchProvider(createTestScanResult()).isEmpty());
1066     }
1067 
1068     /**
1069      * Verify the expectations for sweepCache.
1070      *
1071      * @throws Exception
1072      */
1073     @Test
sweepCache()1074     public void sweepCache() throws Exception {
1075         mManager.sweepCache();
1076         verify(mAnqpCache).sweep();
1077     }
1078 
1079     /**
1080      * Verify that an empty map will be returned if ANQP elements are not cached for the given AP.
1081      *
1082      * @throws Exception
1083      */
1084     @Test
getANQPElementsWithNoMatchFound()1085     public void getANQPElementsWithNoMatchFound() throws Exception {
1086         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
1087         assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty());
1088     }
1089 
1090     /**
1091      * Verify that an expected ANQP elements will be returned if ANQP elements are cached for the
1092      * given AP.
1093      *
1094      * @throws Exception
1095      */
1096     @Test
getANQPElementsWithMatchFound()1097     public void getANQPElementsWithMatchFound() throws Exception {
1098         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1099         anqpElementMap.put(ANQPElementType.ANQPDomName,
1100                 new DomainNameElement(Arrays.asList(new String[] {"test.com"})));
1101         ANQPData entry = new ANQPData(mClock, anqpElementMap);
1102 
1103         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
1104         assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult()));
1105     }
1106 
1107     /**
1108      * Verify that if the Carrier ID is updated during match, the config should be persisted.
1109      */
1110     @Test
getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential()1111     public void getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential() {
1112         // static mocking
1113         MockitoSession session =
1114                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
1115                         InformationElementUtil.class).startMocking();
1116         try {
1117             PasspointProvider provider = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
1118                     TEST_PACKAGE, false, null);
1119             when(provider.tryUpdateCarrierId()).thenReturn(true);
1120             reset(mWifiConfigManager);
1121 
1122             ANQPData entry = new ANQPData(mClock, null);
1123             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
1124             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
1125 
1126             when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
1127             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
1128             when(provider.match(anyMap(), isNull()))
1129                     .thenReturn(PasspointMatch.HomeProvider);
1130 
1131             List<Pair<PasspointProvider, PasspointMatch>> matchedProviders =
1132                     mManager.getAllMatchedProviders(createTestScanResult());
1133 
1134             verify(mWifiConfigManager).saveToStore(eq(true));
1135 
1136         } finally {
1137             session.finishMocking();
1138         }
1139     }
1140     /**
1141      * Verify that an expected map of FQDN and a list of ScanResult will be returned when provided
1142      * scanResults are matched to installed Passpoint profiles.
1143      */
1144     @Test
getAllMatchingFqdnsForScanResults()1145     public void getAllMatchingFqdnsForScanResults() {
1146         // static mocking
1147         MockitoSession session =
1148                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
1149                         InformationElementUtil.class).startMocking();
1150         try {
1151             PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
1152                     TEST_PACKAGE, false, null);
1153             providerHome.getWifiConfig().isHomeProviderNetwork = true;
1154             PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
1155                     TEST_PACKAGE, false, null);
1156             WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
1157                     TEST_UID, "\"PasspointTestSSID\"", true, true,
1158                     TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
1159             PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
1160                     TEST_PACKAGE, wifiConfiguration, false, null);
1161             ANQPData entry = new ANQPData(mClock, null);
1162             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
1163             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
1164 
1165             when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
1166             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
1167             when(providerHome.match(anyMap(), isNull()))
1168                     .thenReturn(PasspointMatch.HomeProvider);
1169             when(providerRoaming.match(anyMap(), isNull()))
1170                     .thenReturn(PasspointMatch.RoamingProvider);
1171             when(providerNone.match(anyMap(), isNull()))
1172                     .thenReturn(PasspointMatch.None);
1173 
1174             Map<String, Map<Integer, List<ScanResult>>> configs =
1175                     mManager.getAllMatchingPasspointProfilesForScanResults(
1176                             createTestScanResults());
1177 
1178             // Expects to be matched with home Provider for each AP (two APs).
1179             assertEquals(2, configs.get(providerHome.getConfig().getUniqueId()).get(
1180                     WifiManager.PASSPOINT_HOME_NETWORK).size());
1181             assertFalse(configs.get(providerHome.getConfig().getUniqueId())
1182                             .containsKey(WifiManager.PASSPOINT_ROAMING_NETWORK));
1183 
1184             // Expects to be matched with roaming Provider for each AP (two APs).
1185             assertEquals(2, configs.get(providerRoaming.getConfig().getUniqueId()).get(
1186                     WifiManager.PASSPOINT_ROAMING_NETWORK).size());
1187             assertFalse(configs.get(providerRoaming.getConfig().getUniqueId())
1188                     .containsKey(WifiManager.PASSPOINT_HOME_NETWORK));
1189 
1190         } finally {
1191             session.finishMocking();
1192         }
1193     }
1194 
1195     /**
1196      * Verify that an expected list of {@link WifiConfiguration} will be returned when provided
1197      * a list of FQDN is matched to installed Passpoint profiles. For suggestion passpoint network,
1198      * will check if that suggestion share credential with user to choose from wifi picker.
1199      */
1200     @Test
getWifiConfigsForPasspointProfiles()1201     public void getWifiConfigsForPasspointProfiles() {
1202         PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
1203                 TEST_PACKAGE, false, null);
1204         PasspointProvider provider2 = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
1205                 TEST_PACKAGE, false, null);
1206         PasspointProvider provider3 = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
1207                 TEST_PACKAGE, false, null);
1208 
1209         assertEquals(3, mManager.getWifiConfigsForPasspointProfiles(
1210                 Arrays.asList(provider1.getConfig().getUniqueId(),
1211                         provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
1212                         TEST_FQDN + "_353ab8c93", TEST_FQDN + "_83765319aca")).size());
1213         PasspointProvider provider4 = addTestProvider(TEST_FQDN + 3, TEST_FRIENDLY_NAME,
1214                 TEST_PACKAGE, true, null);
1215         when(mWifiNetworkSuggestionsManager
1216                 .isPasspointSuggestionSharedWithUser(provider4.getWifiConfig())).thenReturn(false);
1217         assertEquals(3, mManager.getWifiConfigsForPasspointProfiles(
1218                 Arrays.asList(provider1.getConfig().getUniqueId(),
1219                         provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
1220                         provider4.getConfig().getUniqueId(), TEST_FQDN + "_83765319aca")).size());
1221         PasspointProvider provider5 = addTestProvider(TEST_FQDN + 4, TEST_FRIENDLY_NAME,
1222                 TEST_PACKAGE, true, null);
1223         when(mWifiNetworkSuggestionsManager
1224                 .isPasspointSuggestionSharedWithUser(provider5.getWifiConfig())).thenReturn(true);
1225         assertEquals(4, mManager.getWifiConfigsForPasspointProfiles(
1226                 Arrays.asList(provider1.getConfig().getUniqueId(),
1227                         provider2.getConfig().getUniqueId(), provider3.getConfig().getUniqueId(),
1228                         provider4.getConfig().getUniqueId(), provider5.getConfig().getUniqueId()))
1229                 .size());
1230     }
1231 
1232     /**
1233      * Verify that an empty map will be returned when trying to get all matching FQDN for a {@code
1234      * null} {@link ScanResult}.
1235      */
1236     @Test
getAllMatchingFqdnsForScanResultsWithNullScanResult()1237     public void getAllMatchingFqdnsForScanResultsWithNullScanResult() throws Exception {
1238         assertEquals(0,
1239                 mManager.getAllMatchingPasspointProfilesForScanResults(null).size());
1240     }
1241 
1242     /**
1243      * Verify that an empty map will be returned when trying to get a all matching FQDN for a {@link
1244      * ScanResult} with a {@code null} BSSID.
1245      */
1246     @Test
getAllMatchingFqdnsForScanResultsWithNullBSSID()1247     public void getAllMatchingFqdnsForScanResultsWithNullBSSID() throws Exception {
1248         ScanResult scanResult = createTestScanResult();
1249         scanResult.BSSID = null;
1250 
1251         assertEquals(0,
1252                 mManager.getAllMatchingPasspointProfilesForScanResults(
1253                         Arrays.asList(scanResult)).size());
1254     }
1255 
1256     /**
1257      * Verify that an empty map will be returned when trying to get all matching FQDN for a {@link
1258      * ScanResult} with an invalid BSSID.
1259      */
1260     @Test
ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID()1261     public void ggetAllMatchingFqdnsForScanResultsWithInvalidBSSID() throws Exception {
1262         ScanResult scanResult = createTestScanResult();
1263         scanResult.BSSID = "asdfdasfas";
1264 
1265         assertEquals(0,
1266                 mManager.getAllMatchingPasspointProfilesForScanResults(
1267                         Arrays.asList(scanResult)).size());
1268     }
1269 
1270     /**
1271      * Verify that an empty map will be returned when trying to get all matching FQDN for a
1272      * non-Passpoint AP.
1273      */
1274     @Test
getAllMatchingFqdnsForScanResultsForNonPasspointAP()1275     public void getAllMatchingFqdnsForScanResultsForNonPasspointAP() throws Exception {
1276         ScanResult scanResult = createTestScanResult();
1277         scanResult.flags = 0;
1278         assertEquals(0,
1279                 mManager.getAllMatchingPasspointProfilesForScanResults(
1280                         Arrays.asList(scanResult)).size());
1281     }
1282 
1283     /**
1284      * Verify that an empty list will be returned when retrieving OSU providers for an AP with
1285      * null scan result.
1286      *
1287      * @throws Exception
1288      */
1289     @Test
getMatchingOsuProvidersForNullScanResult()1290     public void getMatchingOsuProvidersForNullScanResult() throws Exception {
1291         assertTrue(mManager.getMatchingOsuProviders(null).isEmpty());
1292     }
1293 
1294     /**
1295      * Verify that an empty list will be returned when retrieving OSU providers for an AP with
1296      * invalid BSSID.
1297      *
1298      * @throws Exception
1299      */
1300     @Test
getMatchingOsuProvidersForInvalidBSSID()1301     public void getMatchingOsuProvidersForInvalidBSSID() throws Exception {
1302         ScanResult scanResult = createTestScanResult();
1303         scanResult.BSSID = "asdfdasfas";
1304         assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty());
1305     }
1306 
1307     /**
1308      * Verify that an empty list will be returned when retrieving OSU providers for a
1309      * non-Passpoint AP.
1310      *
1311      * @throws Exception
1312      */
1313     @Test
getMatchingOsuProvidersForNonPasspointAP()1314     public void getMatchingOsuProvidersForNonPasspointAP() throws Exception {
1315         ScanResult scanResult = createTestScanResult();
1316         scanResult.flags = 0;
1317         assertTrue(mManager.getMatchingOsuProviders(Arrays.asList(scanResult)).isEmpty());
1318     }
1319 
1320     /**
1321      * Verify that an empty list will be returned when no match is found from the ANQP cache.
1322      *
1323      * @throws Exception
1324      */
1325     @Test
getMatchingOsuProviderWithNoMatch()1326     public void getMatchingOsuProviderWithNoMatch() throws Exception {
1327         when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null);
1328         assertTrue(
1329                 mManager.getMatchingOsuProviders(Arrays.asList(createTestScanResult())).isEmpty());
1330     }
1331 
1332     /**
1333      * Verify that an expected provider list will be returned when a match is found from
1334      * the ANQP cache with a given list of scanResult.
1335      *
1336      * @throws Exception
1337      */
1338     @Test
getMatchingOsuProvidersWithMatch()1339     public void getMatchingOsuProvidersWithMatch() throws Exception {
1340         // Setup OSU providers ANQP element for AP1.
1341         List<OsuProviderInfo> providerInfoListOfAp1 = new ArrayList<>();
1342         Map<ANQPElementType, ANQPElement> anqpElementMapOfAp1 = new HashMap<>();
1343         Set<OsuProvider> expectedOsuProvidersForDomainId = new HashSet<>();
1344 
1345         // Setup OSU providers ANQP element for AP2.
1346         List<OsuProviderInfo> providerInfoListOfAp2 = new ArrayList<>();
1347         Map<ANQPElementType, ANQPElement> anqpElementMapOfAp2 = new HashMap<>();
1348         Set<OsuProvider> expectedOsuProvidersForDomainId2 = new HashSet<>();
1349         int osuProviderCount = 4;
1350 
1351         // static mocking
1352         MockitoSession session =
1353                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
1354                         InformationElementUtil.class).startMocking();
1355         try {
1356             for (int i = 0; i < osuProviderCount; i++) {
1357                 // Test data.
1358                 String friendlyName = "Test Provider" + i;
1359                 String serviceDescription = "Dummy Service" + i;
1360                 Uri serverUri = Uri.parse("https://" + "test" + i + ".com");
1361                 String nai = "access.test.com";
1362                 List<Integer> methodList = Arrays.asList(1);
1363                 List<I18Name> friendlyNames = Arrays.asList(
1364                         new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH, friendlyName));
1365                 List<I18Name> serviceDescriptions = Arrays.asList(
1366                         new I18Name(Locale.ENGLISH.getLanguage(), Locale.ENGLISH,
1367                                 serviceDescription));
1368                 Map<String, String> friendlyNameMap = new HashMap<>();
1369                 friendlyNames.forEach(e -> friendlyNameMap.put(e.getLanguage(), e.getText()));
1370 
1371                 expectedOsuProvidersForDomainId.add(new OsuProvider(
1372                         (WifiSsid) null, friendlyNameMap, serviceDescription,
1373                         serverUri, nai, methodList));
1374 
1375                 // add All OSU Providers for AP1.
1376                 providerInfoListOfAp1.add(new OsuProviderInfo(
1377                         friendlyNames, serverUri, methodList, null, nai, serviceDescriptions));
1378 
1379                 // add only half of All OSU Providers for AP2.
1380                 if (i >= osuProviderCount / 2) {
1381                     providerInfoListOfAp2.add(new OsuProviderInfo(
1382                             friendlyNames, serverUri, methodList, null, nai, serviceDescriptions));
1383                     expectedOsuProvidersForDomainId2.add(new OsuProvider(
1384                             (WifiSsid) null, friendlyNameMap, serviceDescription,
1385                             serverUri, nai, methodList));
1386                 }
1387             }
1388             anqpElementMapOfAp1.put(ANQPElementType.HSOSUProviders,
1389                     new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID"),
1390                             providerInfoListOfAp1));
1391             ANQPData anqpData = new ANQPData(mClock, anqpElementMapOfAp1);
1392             when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(anqpData);
1393 
1394             anqpElementMapOfAp2.put(ANQPElementType.HSOSUProviders,
1395                     new HSOsuProvidersElement(WifiSsid.createFromAsciiEncoded("Test SSID2"),
1396                             providerInfoListOfAp2));
1397             ANQPData anqpData2 = new ANQPData(mClock, anqpElementMapOfAp2);
1398             when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(anqpData2);
1399 
1400             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
1401 
1402             // ANQP_DOMAIN_ID(TEST_ANQP_KEY)
1403             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
1404             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
1405             assertEquals(mManager.getMatchingOsuProviders(
1406                     Arrays.asList(createTestScanResult())).keySet(),
1407                     expectedOsuProvidersForDomainId);
1408 
1409             // ANQP_DOMAIN_ID2(TEST_ANQP_KEY2)
1410             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
1411             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
1412             assertEquals(mManager.getMatchingOsuProviders(
1413                     createTestScanResults()).keySet(), expectedOsuProvidersForDomainId2);
1414         } finally {
1415             session.finishMocking();
1416         }
1417     }
1418 
1419     /**
1420      * Verify that matching Passpoint configurations will be returned as map with corresponding
1421      * OSU providers.
1422      */
1423     @Test
getMatchingPasspointConfigsForOsuProvidersWithMatch()1424     public void getMatchingPasspointConfigsForOsuProvidersWithMatch() {
1425         PasspointProvider provider1 =
1426                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1427         PasspointProvider provider2 =
1428                 addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null);
1429 
1430         List<OsuProvider> osuProviders = new ArrayList<>();
1431         Map<String, String> friendlyNames = new HashMap<>();
1432         friendlyNames.put("en", "NO-MATCH-NAME");
1433         friendlyNames.put("kr", TEST_FRIENDLY_NAME + 1);
1434 
1435         osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
1436                 friendlyNames));
1437         friendlyNames = new HashMap<>();
1438         friendlyNames.put("en", TEST_FRIENDLY_NAME2);
1439         osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
1440                 friendlyNames));
1441 
1442         Map<OsuProvider, PasspointConfiguration> results =
1443                 mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders);
1444 
1445         assertEquals(2, results.size());
1446         assertThat(Arrays.asList(provider1.getConfig(), provider2.getConfig()),
1447                 containsInAnyOrder(results.values().toArray()));
1448     }
1449 
1450     /**
1451      * Verify that empty map will be returned when there is no matching Passpoint configuration.
1452      */
1453     @Test
getMatchingPasspointConfigsForOsuProvidersWitNoMatch()1454     public void getMatchingPasspointConfigsForOsuProvidersWitNoMatch() {
1455         addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1456         addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME2, TEST_PACKAGE, false, null);
1457 
1458         List<OsuProvider> osuProviders = new ArrayList<>();
1459 
1460         Map<String, String> friendlyNames = new HashMap<>();
1461         friendlyNames.put("en", "NO-MATCH-NAME");
1462         osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
1463                 friendlyNames));
1464         friendlyNames = new HashMap<>();
1465         friendlyNames.put("en", "NO-MATCH-NAME-2");
1466         osuProviders.add(PasspointProvisioningTestUtil.generateOsuProviderWithFriendlyName(true,
1467                 friendlyNames));
1468 
1469         assertEquals(0, mManager.getMatchingPasspointConfigsForOsuProviders(osuProviders).size());
1470     }
1471 
1472     /**
1473      * Verify that the provider list maintained by the PasspointManager after the list is updated
1474      * in the data source.
1475      *
1476      * @throws Exception
1477      */
1478     @Test
verifyProvidersAfterDataSourceUpdate()1479     public void verifyProvidersAfterDataSourceUpdate() throws Exception {
1480         // Update the provider list in the data source.
1481         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
1482                 TEST_FRIENDLY_NAME);
1483         PasspointProvider provider = createMockProvider(config);
1484         List<PasspointProvider> providers = new ArrayList<>();
1485         providers.add(provider);
1486         mUserDataSource.setProviders(providers);
1487 
1488         // Verify the providers maintained by PasspointManager.
1489         assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size());
1490         assertEquals(config, mManager.getProviderConfigs(TEST_CREATOR_UID, true).get(0));
1491     }
1492 
1493     /**
1494      * Verify that the provider index used by PasspointManager is updated after it is updated in
1495      * the data source.
1496      *
1497      * @throws Exception
1498      */
1499     @Test
verifyProviderIndexAfterDataSourceUpdate()1500     public void verifyProviderIndexAfterDataSourceUpdate() throws Exception {
1501         long providerIndex = 9;
1502         mSharedDataSource.setProviderIndex(providerIndex);
1503         assertEquals(providerIndex, mSharedDataSource.getProviderIndex());
1504 
1505         // Add a provider.
1506         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
1507                 TEST_FRIENDLY_NAME);
1508         PasspointProvider provider = createMockProvider(config);
1509         // Verify the provider ID used to create the new provider.
1510         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
1511                 eq(mWifiCarrierInfoManager), eq(providerIndex), eq(TEST_CREATOR_UID),
1512                 eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
1513 
1514         assertTrue(
1515                 mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false, true));
1516         verifyInstalledConfig(config);
1517         reset(mWifiConfigManager);
1518     }
1519 
1520     /**
1521      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
1522      * adding a legacy Passpoint configuration containing a valid user credential.
1523      *
1524      * @throws Exception
1525      */
1526     @Test
addLegacyPasspointConfigWithUserCredential()1527     public void addLegacyPasspointConfigWithUserCredential() throws Exception {
1528         // Test data.
1529         String fqdn = "test.com";
1530         String friendlyName = "Friendly Name";
1531         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1532         String realm = "realm.com";
1533         String username = "username";
1534         String password = "password";
1535         byte[] base64EncodedPw =
1536                 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
1537         String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
1538         String caCertificateAlias = "CaCert";
1539 
1540         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1541         WifiConfiguration wifiConfig = new WifiConfiguration();
1542         wifiConfig.FQDN = fqdn;
1543         wifiConfig.providerFriendlyName = friendlyName;
1544         wifiConfig.roamingConsortiumIds = rcOIs;
1545         wifiConfig.enterpriseConfig.setIdentity(username);
1546         wifiConfig.enterpriseConfig.setPassword(password);
1547         wifiConfig.enterpriseConfig.setRealm(realm);
1548         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
1549         wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
1550         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
1551 
1552         // Setup expected {@link PasspointConfiguration}
1553         PasspointConfiguration passpointConfig = new PasspointConfiguration();
1554         HomeSp homeSp = new HomeSp();
1555         homeSp.setFqdn(fqdn);
1556         homeSp.setFriendlyName(friendlyName);
1557         homeSp.setRoamingConsortiumOis(rcOIs);
1558         passpointConfig.setHomeSp(homeSp);
1559         Credential credential = new Credential();
1560         Credential.UserCredential userCredential = new Credential.UserCredential();
1561         userCredential.setUsername(username);
1562         userCredential.setPassword(encodedPasswordStr);
1563         userCredential.setEapType(EAPConstants.EAP_TTLS);
1564         userCredential.setNonEapInnerMethod("PAP");
1565         credential.setUserCredential(userCredential);
1566         credential.setRealm(realm);
1567         passpointConfig.setCredential(credential);
1568 
1569         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1570         verifyInstalledConfig(passpointConfig);
1571     }
1572 
1573     /**
1574      * Verify that adding a legacy Passpoint configuration containing user credential will
1575      * fail when client certificate is not provided.
1576      *
1577      * @throws Exception
1578      */
1579     @Test
addLegacyPasspointConfigWithUserCredentialWithoutCaCert()1580     public void addLegacyPasspointConfigWithUserCredentialWithoutCaCert() throws Exception {
1581         // Test data.
1582         String fqdn = "test.com";
1583         String friendlyName = "Friendly Name";
1584         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1585         String realm = "realm.com";
1586         String username = "username";
1587         String password = "password";
1588         byte[] base64EncodedPw =
1589                 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
1590         String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
1591 
1592         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1593         WifiConfiguration wifiConfig = new WifiConfiguration();
1594         wifiConfig.FQDN = fqdn;
1595         wifiConfig.providerFriendlyName = friendlyName;
1596         wifiConfig.roamingConsortiumIds = rcOIs;
1597         wifiConfig.enterpriseConfig.setIdentity(username);
1598         wifiConfig.enterpriseConfig.setPassword(password);
1599         wifiConfig.enterpriseConfig.setRealm(realm);
1600         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
1601         wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
1602 
1603         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1604     }
1605 
1606     /**
1607      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
1608      * adding a legacy Passpoint configuration containing a valid SIM credential.
1609      *
1610      * @throws Exception
1611      */
1612     @Test
addLegacyPasspointConfigWithSimCredential()1613     public void addLegacyPasspointConfigWithSimCredential() throws Exception {
1614         // Test data.
1615         String fqdn = "test.com";
1616         String friendlyName = "Friendly Name";
1617         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1618         String realm = "realm.com";
1619         String imsi = "1234";
1620 
1621         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1622         WifiConfiguration wifiConfig = new WifiConfiguration();
1623         wifiConfig.FQDN = fqdn;
1624         wifiConfig.providerFriendlyName = friendlyName;
1625         wifiConfig.roamingConsortiumIds = rcOIs;
1626         wifiConfig.enterpriseConfig.setRealm(realm);
1627         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
1628         wifiConfig.enterpriseConfig.setPlmn(imsi);
1629 
1630         // Setup expected {@link PasspointConfiguration}
1631         PasspointConfiguration passpointConfig = new PasspointConfiguration();
1632         HomeSp homeSp = new HomeSp();
1633         homeSp.setFqdn(fqdn);
1634         homeSp.setFriendlyName(friendlyName);
1635         homeSp.setRoamingConsortiumOis(rcOIs);
1636         passpointConfig.setHomeSp(homeSp);
1637         Credential credential = new Credential();
1638         Credential.SimCredential simCredential = new Credential.SimCredential();
1639         simCredential.setEapType(EAPConstants.EAP_SIM);
1640         simCredential.setImsi(imsi);
1641         credential.setSimCredential(simCredential);
1642         credential.setRealm(realm);
1643         passpointConfig.setCredential(credential);
1644 
1645         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1646         verifyInstalledConfig(passpointConfig);
1647     }
1648 
1649     /**
1650      * Verify that a PasspointProvider with expected PasspointConfiguration will be installed when
1651      * adding a legacy Passpoint configuration containing a valid certificate credential.
1652      *
1653      * @throws Exception
1654      */
1655     @Test
addLegacyPasspointConfigWithCertCredential()1656     public void addLegacyPasspointConfigWithCertCredential() throws Exception {
1657         // Test data.
1658         String fqdn = "test.com";
1659         String friendlyName = "Friendly Name";
1660         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1661         String realm = "realm.com";
1662         String caCertificateAlias = "CaCert";
1663         String clientCertificateAlias = "ClientCert";
1664 
1665         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1666         WifiConfiguration wifiConfig = new WifiConfiguration();
1667         wifiConfig.FQDN = fqdn;
1668         wifiConfig.providerFriendlyName = friendlyName;
1669         wifiConfig.roamingConsortiumIds = rcOIs;
1670         wifiConfig.enterpriseConfig.setRealm(realm);
1671         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
1672         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
1673         wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
1674 
1675         // Setup expected {@link PasspointConfiguration}
1676         PasspointConfiguration passpointConfig = new PasspointConfiguration();
1677         HomeSp homeSp = new HomeSp();
1678         homeSp.setFqdn(fqdn);
1679         homeSp.setFriendlyName(friendlyName);
1680         homeSp.setRoamingConsortiumOis(rcOIs);
1681         passpointConfig.setHomeSp(homeSp);
1682         Credential credential = new Credential();
1683         Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
1684         certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
1685         credential.setCertCredential(certCredential);
1686         credential.setRealm(realm);
1687         passpointConfig.setCredential(credential);
1688 
1689         assertTrue(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1690         verifyInstalledConfig(passpointConfig);
1691     }
1692 
1693     /**
1694      * Verify that adding a legacy Passpoint configuration containing certificate credential will
1695      * fail when CA certificate is not provided.
1696      *
1697      * @throws Exception
1698      */
1699     @Test
addLegacyPasspointConfigWithCertCredentialWithoutCaCert()1700     public void addLegacyPasspointConfigWithCertCredentialWithoutCaCert() throws Exception {
1701         // Test data.
1702         String fqdn = "test.com";
1703         String friendlyName = "Friendly Name";
1704         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1705         String realm = "realm.com";
1706         String clientCertificateAlias = "ClientCert";
1707 
1708         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1709         WifiConfiguration wifiConfig = new WifiConfiguration();
1710         wifiConfig.FQDN = fqdn;
1711         wifiConfig.providerFriendlyName = friendlyName;
1712         wifiConfig.roamingConsortiumIds = rcOIs;
1713         wifiConfig.enterpriseConfig.setRealm(realm);
1714         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
1715         wifiConfig.enterpriseConfig.setClientCertificateAlias(clientCertificateAlias);
1716 
1717         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1718     }
1719 
1720     /**
1721      * Verify that adding a legacy Passpoint configuration containing certificate credential will
1722      * fail when client certificate is not provided.
1723      *
1724      * @throws Exception
1725      */
1726     @Test
addLegacyPasspointConfigWithCertCredentialWithoutClientCert()1727     public void addLegacyPasspointConfigWithCertCredentialWithoutClientCert() throws Exception {
1728         // Test data.
1729         String fqdn = "test.com";
1730         String friendlyName = "Friendly Name";
1731         long[] rcOIs = new long[] {0x1234L, 0x2345L};
1732         String realm = "realm.com";
1733         String caCertificateAlias = "CaCert";
1734 
1735         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1736         WifiConfiguration wifiConfig = new WifiConfiguration();
1737         wifiConfig.FQDN = fqdn;
1738         wifiConfig.providerFriendlyName = friendlyName;
1739         wifiConfig.roamingConsortiumIds = rcOIs;
1740         wifiConfig.enterpriseConfig.setRealm(realm);
1741         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
1742         wifiConfig.enterpriseConfig.setCaCertificateAlias(caCertificateAlias);
1743 
1744         assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
1745     }
1746 
1747     /**
1748      * Verify that the provider's "hasEverConnected" flag will be set to true and the associated
1749      * metric is updated after the provider was used to successfully connect to a Passpoint
1750      * network for the first time.
1751      *
1752      * @throws Exception
1753      */
1754     @Test
providerNetworkConnectedFirstTime()1755     public void providerNetworkConnectedFirstTime() throws Exception {
1756         PasspointProvider provider =
1757                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1758         when(provider.getHasEverConnected()).thenReturn(false);
1759         mManager.onPasspointNetworkConnected(provider.getConfig().getUniqueId());
1760         verify(provider).setHasEverConnected(eq(true));
1761     }
1762 
1763     /**
1764      * Verify that the provider's "hasEverConnected" flag the associated metric is not updated
1765      * after the provider was used to successfully connect to a Passpoint network for non-first
1766      * time.
1767      *
1768      * @throws Exception
1769      */
1770     @Test
providerNetworkConnectedNotFirstTime()1771     public void providerNetworkConnectedNotFirstTime() throws Exception {
1772         PasspointProvider provider =
1773                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1774         when(provider.getHasEverConnected()).thenReturn(true);
1775         mManager.onPasspointNetworkConnected(TEST_FQDN);
1776         verify(provider, never()).setHasEverConnected(anyBoolean());
1777     }
1778 
1779     /**
1780      * Verify that the expected Passpoint metrics are updated when
1781      * {@link PasspointManager#updateMetrics} is invoked.
1782      *
1783      * @throws Exception
1784      */
1785     @Test
updateMetrics()1786     public void updateMetrics() {
1787         PasspointProvider provider =
1788                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1789         ArgumentCaptor<Map<String, PasspointProvider>> argCaptor = ArgumentCaptor.forClass(
1790                 Map.class);
1791         // Provider have not provided a successful network connection.
1792         int expectedInstalledProviders = 1;
1793         int expectedConnectedProviders = 0;
1794         when(provider.getHasEverConnected()).thenReturn(false);
1795         mManager.updateMetrics();
1796         verify(mWifiMetrics).updateSavedPasspointProfiles(
1797                 eq(expectedInstalledProviders), eq(expectedConnectedProviders));
1798 
1799         verify(mWifiMetrics).updateSavedPasspointProfilesInfo(argCaptor.capture());
1800         assertEquals(expectedInstalledProviders, argCaptor.getValue().size());
1801         assertEquals(provider, argCaptor.getValue().get(provider.getConfig().getUniqueId()));
1802         reset(mWifiMetrics);
1803 
1804         // Provider have provided a successful network connection.
1805         expectedConnectedProviders = 1;
1806         when(provider.getHasEverConnected()).thenReturn(true);
1807         mManager.updateMetrics();
1808         verify(mWifiMetrics).updateSavedPasspointProfiles(
1809                 eq(expectedInstalledProviders), eq(expectedConnectedProviders));
1810     }
1811 
1812     /**
1813      * Verify Passpoint Manager's provisioning APIs by invoking methods in PasspointProvisioner for
1814      * initiailization and provisioning a provider.
1815      */
1816     @Test
verifyPasspointProvisioner()1817     public void verifyPasspointProvisioner() {
1818         mManager.initializeProvisioner(mLooper.getLooper());
1819         verify(mPasspointProvisioner).init(any(Looper.class));
1820         when(mPasspointProvisioner.startSubscriptionProvisioning(anyInt(), any(OsuProvider.class),
1821                 any(IProvisioningCallback.class))).thenReturn(true);
1822         OsuProvider osuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
1823         assertEquals(true,
1824                 mManager.startSubscriptionProvisioning(TEST_UID, osuProvider, mCallback));
1825     }
1826 
1827     /**
1828      * Verify that the corresponding Passpoint provider is removed when the app is disabled.
1829      */
1830     @Test
verifyRemovingPasspointProfilesWhenAppIsDisabled()1831     public void verifyRemovingPasspointProfilesWhenAppIsDisabled() {
1832         WifiConfiguration currentConfiguration = WifiConfigurationTestUtil.createPasspointNetwork();
1833         currentConfiguration.FQDN = TEST_FQDN;
1834         when(mClientModeImpl.getCurrentWifiConfiguration()).thenReturn(currentConfiguration);
1835         PasspointProvider passpointProvider =
1836                 addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE, false, null);
1837         currentConfiguration.setPasspointUniqueId(passpointProvider.getConfig().getUniqueId());
1838         verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE),
1839                 mAppOpChangedListenerCaptor.capture());
1840         assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size());
1841         AppOpsManager.OnOpChangedListener listener = mAppOpChangedListenerCaptor.getValue();
1842         assertNotNull(listener);
1843 
1844         // Disallow change wifi state & ensure we remove the profiles from database.
1845         when(mAppOpsManager.unsafeCheckOpNoThrow(
1846                 OPSTR_CHANGE_WIFI_STATE, TEST_CREATOR_UID,
1847                 TEST_PACKAGE))
1848                 .thenReturn(MODE_IGNORED);
1849         listener.onOpChanged(OPSTR_CHANGE_WIFI_STATE, TEST_PACKAGE);
1850         mLooper.dispatchAll();
1851 
1852         verify(mAppOpsManager).stopWatchingMode(mAppOpChangedListenerCaptor.getValue());
1853         verify(mClientModeImpl).disconnectCommand();
1854         assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, true).isEmpty());
1855     }
1856 
1857     /**
1858      * Verify that removing a provider with a different UID will not succeed.
1859      *
1860      * @throws Exception
1861      */
1862     @Test
removeGetProviderWithDifferentUid()1863     public void removeGetProviderWithDifferentUid() throws Exception {
1864         PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
1865                 TEST_REALM);
1866         PasspointProvider provider = createMockProvider(config);
1867         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
1868                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
1869                 eq(false))).thenReturn(provider);
1870         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
1871                 false, true));
1872         verifyInstalledConfig(config);
1873         verify(mWifiConfigManager).saveToStore(true);
1874         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
1875         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
1876         reset(mWifiMetrics);
1877         reset(mWifiConfigManager);
1878 
1879         // no profiles available for TEST_UID
1880         assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty());
1881         // 1 profile available for TEST_CREATOR_UID
1882         assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
1883 
1884         // Remove the provider as a non-privileged non-creator app.
1885         assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN));
1886         verify(provider, never()).uninstallCertsAndKeys();
1887         verify(mWifiConfigManager, never()).saveToStore(true);
1888         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
1889         verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
1890 
1891         // no profiles available for TEST_UID
1892         assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty());
1893         // 1 profile available for TEST_CREATOR_UID
1894         assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
1895     }
1896 
1897     /**
1898      * Verify that adding a suggestion provider with a valid configuration and user credential will
1899      * succeed.
1900      *
1901      * @throws Exception
1902      */
1903     @Test
addRemoveSuggestionProvider()1904     public void addRemoveSuggestionProvider() throws Exception {
1905         PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
1906                 TEST_FRIENDLY_NAME);
1907         PasspointProvider provider = createMockProvider(config);
1908         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
1909         when(provider.isFromSuggestion()).thenReturn(true);
1910         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
1911                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
1912                 eq(true))).thenReturn(provider);
1913         assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE,
1914                 true, true));
1915         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
1916         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
1917         verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE),
1918                 eq(TEST_PACKAGE), any(AppOpsManager.OnOpChangedListener.class));
1919         assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
1920         reset(mWifiMetrics);
1921         reset(mWifiConfigManager);
1922 
1923         // Verify content in the data source.
1924         List<PasspointProvider> providers = mUserDataSource.getProviders();
1925         assertEquals(1, providers.size());
1926         assertEquals(config, providers.get(0).getConfig());
1927         // Provider index start with 0, should be 1 after adding a provider.
1928         assertEquals(1, mSharedDataSource.getProviderIndex());
1929 
1930         // Remove from another Suggestor app, should fail.
1931         assertFalse(mManager.removeProvider(TEST_UID, false, null, TEST_FQDN));
1932         verify(provider, never()).uninstallCertsAndKeys();
1933         verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
1934                 provider.getWifiConfig().getKey());
1935         verify(mWifiConfigManager, never()).saveToStore(true);
1936         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
1937         verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
1938         verify(mAppOpsManager, never()).stopWatchingMode(
1939                 any(AppOpsManager.OnOpChangedListener.class));
1940         // Verify content in the data source.
1941         providers = mUserDataSource.getProviders();
1942         assertEquals(1, providers.size());
1943         assertEquals(config, providers.get(0).getConfig());
1944         // Provider index start with 0, should be 1 after adding a provider.
1945         assertEquals(1, mSharedDataSource.getProviderIndex());
1946         reset(mWifiMetrics);
1947         reset(mWifiConfigManager);
1948 
1949         // Remove the provider from same app.
1950         assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
1951         verify(provider).uninstallCertsAndKeys();
1952         verify(mWifiConfigManager).removePasspointConfiguredNetwork(
1953                 provider.getWifiConfig().getKey());
1954         verify(mWifiConfigManager).saveToStore(true);
1955         verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
1956         verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
1957         verify(mAppOpsManager, never()).stopWatchingMode(
1958                 any(AppOpsManager.OnOpChangedListener.class));
1959 
1960         // Verify content in the data source.
1961         assertTrue(mUserDataSource.getProviders().isEmpty());
1962         // Removing a provider should not change the provider index.
1963         assertEquals(1, mSharedDataSource.getProviderIndex());
1964     }
1965 
1966     /**
1967      * Verify that adding a suggestion  provider with the same base domain as the existing
1968      * suggestion provider from same app will succeed, and verify that the new provider is
1969      * added along with the existing provider.
1970      *
1971      * @throws Exception
1972      */
1973     @Test
addSuggestionProviderWithExistingConfig()1974     public void addSuggestionProviderWithExistingConfig() throws Exception {
1975         // Add a provider with the original configuration.
1976         PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
1977                 TEST_REALM);
1978         PasspointProvider origProvider = createMockProvider(origConfig);
1979         when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
1980         when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
1981                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
1982                 eq(true))).thenReturn(origProvider);
1983         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
1984                 true, true));
1985         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
1986         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
1987         reset(mWifiMetrics);
1988         reset(mWifiConfigManager);
1989 
1990         // Verify data source content.
1991         List<PasspointProvider> origProviders = mUserDataSource.getProviders();
1992         assertEquals(1, origProviders.size());
1993         assertEquals(origConfig, origProviders.get(0).getConfig());
1994         assertEquals(1, mSharedDataSource.getProviderIndex());
1995 
1996         // Add same provider as existing suggestion provider
1997         // This should be no WifiConfig deletion
1998         WifiConfiguration origWifiConfig = origProvider.getWifiConfig();
1999         origWifiConfig.fromWifiNetworkSuggestion = true;
2000         origWifiConfig.creatorUid = TEST_CREATOR_UID;
2001         origWifiConfig.creatorName = TEST_PACKAGE;
2002         when(mWifiConfigManager.getConfiguredNetwork(origWifiConfig.getKey()))
2003                 .thenReturn(origWifiConfig);
2004         when(mWifiConfigManager.addOrUpdateNetwork(
2005                 origWifiConfig, TEST_CREATOR_UID, TEST_PACKAGE))
2006                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
2007         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
2008                 true, true));
2009         verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
2010                 origWifiConfig.getKey());
2011         verify(mWifiConfigManager).addOrUpdateNetwork(
2012                 argThat((c) -> c.FQDN.equals(TEST_FQDN)), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE));
2013         verify(mWifiConfigManager).allowAutojoin(TEST_NETWORK_ID, origWifiConfig.allowAutojoin);
2014         verify(mWifiConfigManager).saveToStore(true);
2015         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2016         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2017         assertEquals(2, mSharedDataSource.getProviderIndex());
2018         reset(mWifiMetrics);
2019         reset(mWifiConfigManager);
2020 
2021         // Add another provider with the same base domain as the existing saved provider.
2022         // This should replace the existing provider with the new configuration.
2023         PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
2024                 TEST_FRIENDLY_NAME);
2025         PasspointProvider newProvider = createMockProvider(newConfig);
2026         when(newProvider.isFromSuggestion()).thenReturn(true);
2027         when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE);
2028         when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
2029                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2030                 eq(true))).thenReturn(newProvider);
2031         assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
2032                 true, true));
2033         verify(mWifiConfigManager).saveToStore(true);
2034         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2035         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2036 
2037         // Verify data source content.
2038         List<PasspointProvider> newProviders = mUserDataSource.getProviders();
2039         assertEquals(2, newProviders.size());
2040         assertTrue(newConfig.equals(newProviders.get(0).getConfig())
2041                 || newConfig.equals(newProviders.get(1).getConfig()));
2042         assertTrue(origConfig.equals(newProviders.get(0).getConfig())
2043                 || origConfig.equals(newProviders.get(1).getConfig()));
2044         assertEquals(3, mSharedDataSource.getProviderIndex());
2045     }
2046 
2047     /**
2048      * Verify that adding a saved provider with the same base domain as the existing
2049      * suggestion provider will succeed, and verify that the new provider with the new configuration
2050      * is added along with the existing provider.
2051      *
2052      * @throws Exception
2053      */
2054     @Test
addSavedProviderWithExistingSuggestionConfig()2055     public void addSavedProviderWithExistingSuggestionConfig() throws Exception {
2056         // Add a provider with the original configuration.
2057         PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
2058                 TEST_REALM);
2059         PasspointProvider origProvider = createMockProvider(origConfig);
2060         when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
2061         when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
2062                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2063                 eq(true))).thenReturn(origProvider);
2064         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE,
2065                 true, true));
2066         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2067         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2068         reset(mWifiMetrics);
2069         reset(mWifiConfigManager);
2070 
2071         // Verify data source content.
2072         List<PasspointProvider> origProviders = mUserDataSource.getProviders();
2073         assertEquals(1, origProviders.size());
2074         assertEquals(origConfig, origProviders.get(0).getConfig());
2075         assertEquals(1, mSharedDataSource.getProviderIndex());
2076 
2077         // Add another provider with the same base domain as the existing saved provider.
2078         // This should replace the existing provider with the new configuration.
2079         PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
2080                 TEST_FRIENDLY_NAME);
2081         PasspointProvider newProvider = createMockProvider(newConfig);
2082         when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
2083                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2084                 eq(false))).thenReturn(newProvider);
2085         assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE,
2086                 false, true));
2087         verify(mWifiConfigManager).saveToStore(true);
2088         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2089         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2090 
2091         // Verify data source content.
2092         List<PasspointProvider> newProviders = mUserDataSource.getProviders();
2093         assertEquals(2, newProviders.size());
2094         assertTrue(newConfig.equals(newProviders.get(0).getConfig())
2095                 || newConfig.equals(newProviders.get(1).getConfig()));
2096         assertTrue(origConfig.equals(newProviders.get(0).getConfig())
2097                 || origConfig.equals(newProviders.get(1).getConfig()));
2098         assertEquals(2, mSharedDataSource.getProviderIndex());
2099     }
2100 
2101     /**
2102      * Verify that adding a suggestion provider with the same base domain as the existing provider
2103      * from different apps will add a new provider.
2104      *
2105      * @throws Exception
2106      */
2107     @Test
addSuggestionProviderWithExistingConfigFromDifferentSource()2108     public void addSuggestionProviderWithExistingConfigFromDifferentSource() throws Exception {
2109         // Add a provider with the original configuration.
2110         PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
2111                 TEST_REALM);
2112         PasspointProvider origProvider = createMockProvider(origConfig);
2113         when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
2114         when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
2115                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2116                 eq(false))).thenReturn(origProvider);
2117         assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false,
2118                 true));
2119         verifyInstalledConfig(origConfig);
2120         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2121         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2122         reset(mWifiMetrics);
2123         reset(mWifiConfigManager);
2124 
2125         // Verify data source content.
2126         List<PasspointProvider> origProviders = mUserDataSource.getProviders();
2127         assertEquals(1, origProviders.size());
2128         assertEquals(origConfig, origProviders.get(0).getConfig());
2129         assertEquals(1, mSharedDataSource.getProviderIndex());
2130 
2131         // Add another provider with the same base domain as the existing saved provider but from
2132         // different app. This should not replace the existing provider with the new configuration
2133         // but add another one.
2134         PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
2135                 TEST_FRIENDLY_NAME);
2136         PasspointProvider newProvider = createMockProvider(newConfig);
2137         when(newProvider.isFromSuggestion()).thenReturn(true);
2138         when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE1);
2139         when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
2140                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1),
2141                 eq(true))).thenReturn(newProvider);
2142         assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE1, true,
2143                 true));
2144         verify(mWifiConfigManager).saveToStore(true);
2145         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2146         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2147 
2148         // Verify data source content.
2149         List<PasspointProvider> newProviders = mUserDataSource.getProviders();
2150         assertEquals(2, newProviders.size());
2151         assertTrue(origConfig.equals(newProviders.get(0).getConfig())
2152                 || origConfig.equals(newProviders.get(1).getConfig()));
2153 
2154         assertEquals(2, mSharedDataSource.getProviderIndex());
2155     }
2156 
2157     /**
2158      * Verify that the HomeProvider provider will be returned when a HomeProvider profile has
2159      * not expired and RoamingProvider expiration is unset (still valid).
2160      *
2161      * @throws Exception
2162      */
2163     @Test
matchHomeProviderWhenHomeProviderNotExpired()2164     public void matchHomeProviderWhenHomeProviderNotExpired() throws Exception {
2165         // static mocking
2166         MockitoSession session =
2167                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
2168                         InformationElementUtil.class).startMocking();
2169         try {
2170             PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2171                     TEST_PACKAGE, false, null);
2172             providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
2173                     System.currentTimeMillis() + 100000);
2174             providerHome.getWifiConfig().isHomeProviderNetwork = true;
2175             PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
2176                     TEST_PACKAGE, false, null);
2177             WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
2178                     TEST_UID, "\"PasspointTestSSID\"", true, true,
2179                     TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
2180             PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
2181                     TEST_PACKAGE, wifiConfiguration, false, null);
2182             ANQPData entry = new ANQPData(mClock, null);
2183             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
2184             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
2185 
2186             when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
2187             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
2188             when(providerHome.match(anyMap(), isNull()))
2189                     .thenReturn(PasspointMatch.HomeProvider);
2190             when(providerRoaming.match(anyMap(), isNull()))
2191                     .thenReturn(PasspointMatch.RoamingProvider);
2192             when(providerNone.match(anyMap(), isNull()))
2193                     .thenReturn(PasspointMatch.None);
2194 
2195             List<Pair<PasspointProvider, PasspointMatch>> results =
2196                     mManager.matchProvider(createTestScanResult());
2197             Pair<PasspointProvider, PasspointMatch> result = results.get(0);
2198 
2199             assertEquals(PasspointMatch.HomeProvider, result.second);
2200             assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
2201 
2202         } finally {
2203             session.finishMocking();
2204         }
2205     }
2206 
2207     /**
2208      * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
2209      * expired and RoamingProvider expiration is unset (still valid).
2210      *
2211      * @throws Exception
2212      */
2213     @Test
matchRoamingProviderUnsetWhenHomeProviderExpired()2214     public void matchRoamingProviderUnsetWhenHomeProviderExpired() throws Exception {
2215         // static mocking
2216         MockitoSession session =
2217                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
2218                         InformationElementUtil.class).startMocking();
2219         try {
2220             PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2221                     TEST_PACKAGE, false, null);
2222             providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
2223                     System.currentTimeMillis() - 10000);
2224             providerHome.getWifiConfig().isHomeProviderNetwork = true;
2225             PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
2226                     TEST_PACKAGE, false, null);
2227             WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
2228                     TEST_UID, "\"PasspointTestSSID\"", true, true,
2229                     TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
2230             PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
2231                     TEST_PACKAGE, wifiConfiguration, false, null);
2232             ANQPData entry = new ANQPData(mClock, null);
2233             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
2234             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
2235 
2236             when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
2237             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
2238             when(providerHome.match(anyMap(), isNull()))
2239                     .thenReturn(PasspointMatch.HomeProvider);
2240             when(providerRoaming.match(anyMap(), isNull()))
2241                     .thenReturn(PasspointMatch.RoamingProvider);
2242             when(providerNone.match(anyMap(), isNull()))
2243                     .thenReturn(PasspointMatch.None);
2244 
2245             List<Pair<PasspointProvider, PasspointMatch>> results =
2246                     mManager.matchProvider(createTestScanResult());
2247             Pair<PasspointProvider, PasspointMatch> result = results.get(0);
2248 
2249             assertEquals(PasspointMatch.RoamingProvider, result.second);
2250             assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
2251 
2252         } finally {
2253             session.finishMocking();
2254         }
2255     }
2256 
2257     /**
2258      * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
2259      * expired and RoamingProvider expiration is still valid.
2260      *
2261      * @throws Exception
2262      */
2263     @Test
matchRoamingProviderNonExpiredWhenHomeProviderExpired()2264     public void matchRoamingProviderNonExpiredWhenHomeProviderExpired() throws Exception {
2265         // static mocking
2266         MockitoSession session =
2267                 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
2268                         InformationElementUtil.class).startMocking();
2269         try {
2270             PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2271                     TEST_PACKAGE, false, null);
2272             providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
2273                     System.currentTimeMillis() - 10000);
2274             providerHome.getWifiConfig().isHomeProviderNetwork = true;
2275             PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
2276                     TEST_PACKAGE, false, null);
2277             providerRoaming.getConfig().setSubscriptionExpirationTimeInMillis(
2278                     System.currentTimeMillis() + 100000);
2279             WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.generateWifiConfig(-1,
2280                     TEST_UID, "\"PasspointTestSSID\"", true, true,
2281                     TEST_FQDN + 2, TEST_FRIENDLY_NAME, SECURITY_EAP);
2282             PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
2283                     TEST_PACKAGE, wifiConfiguration, false, null);
2284             ANQPData entry = new ANQPData(mClock, null);
2285             InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
2286             vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
2287 
2288             when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
2289             when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
2290             when(providerHome.match(anyMap(), isNull()))
2291                     .thenReturn(PasspointMatch.HomeProvider);
2292             when(providerRoaming.match(anyMap(), isNull()))
2293                     .thenReturn(PasspointMatch.RoamingProvider);
2294             when(providerNone.match(anyMap(), isNull()))
2295                     .thenReturn(PasspointMatch.None);
2296 
2297             List<Pair<PasspointProvider, PasspointMatch>> results =
2298                     mManager.matchProvider(createTestScanResult());
2299             Pair<PasspointProvider, PasspointMatch> result = results.get(0);
2300 
2301             assertEquals(PasspointMatch.RoamingProvider, result.second);
2302             assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
2303 
2304         } finally {
2305             session.finishMocking();
2306         }
2307     }
2308 
2309     /**
2310      * Verify add untrusted passpoint network from suggestion success.
2311      */
2312     @Test
testAddUntrustedPasspointNetworkFromSuggestion()2313     public void testAddUntrustedPasspointNetworkFromSuggestion() {
2314         WifiConfiguration wifiConfig = new WifiConfiguration();
2315         wifiConfig.FQDN = TEST_FQDN;
2316         PasspointConfiguration config =
2317                 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
2318         PasspointProvider provider = createMockProvider(config, wifiConfig, true);
2319         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
2320                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2321                 eq(true))).thenReturn(provider);
2322         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
2323         assertTrue(mManager.addOrUpdateProvider(
2324                 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
2325         verify(provider).setTrusted(false);
2326     }
2327 
2328     /**
2329      * Verify add untrusted passpoint network not from suggestion fail.
2330      */
2331     @Test
testAddUntrustedPasspointNetworkNotFromSuggestion()2332     public void testAddUntrustedPasspointNetworkNotFromSuggestion() {
2333         WifiConfiguration wifiConfig = new WifiConfiguration();
2334         wifiConfig.FQDN = TEST_FQDN;
2335         PasspointConfiguration config =
2336                 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
2337         PasspointProvider provider = createMockProvider(config, wifiConfig, false);
2338         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
2339                 eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2340                 eq(true))).thenReturn(provider);
2341         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
2342         assertFalse(mManager.addOrUpdateProvider(
2343                 config, TEST_CREATOR_UID, TEST_PACKAGE, false, false));
2344         verify(provider, never()).setTrusted(false);
2345     }
2346 
2347     /**
2348      * Verify that the ScanResults(Access Points) are returned when it may be
2349      * authenticated with the provided passpoint configuration as roaming match.
2350      */
2351     @Test
getMatchingScanResultsTestWithRoamingMatch()2352     public void getMatchingScanResultsTestWithRoamingMatch() {
2353         PasspointConfiguration config = mock(PasspointConfiguration.class);
2354         PasspointProvider mockProvider = mock(PasspointProvider.class);
2355         when(mObjectFactory.makePasspointProvider(config, null,
2356                 mWifiCarrierInfoManager, 0, 0, null, false))
2357                 .thenReturn(mockProvider);
2358         List<ScanResult> scanResults = new ArrayList<>() {{
2359                 add(mock(ScanResult.class));
2360             }};
2361         when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
2362                 .thenReturn(PasspointMatch.RoamingProvider);
2363 
2364         List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
2365 
2366         assertEquals(1, testResults.size());
2367     }
2368 
2369     /**
2370      * Verify that the ScanResults(Access Points) are returned when it may be
2371      * authenticated with the provided passpoint configuration as home match.
2372      */
2373     @Test
getMatchingScanResultsTestWithHomeMatch()2374     public void getMatchingScanResultsTestWithHomeMatch() {
2375         PasspointConfiguration config = mock(PasspointConfiguration.class);
2376         PasspointProvider mockProvider = mock(PasspointProvider.class);
2377         when(mObjectFactory.makePasspointProvider(config, null,
2378                 mWifiCarrierInfoManager, 0, 0, null, false))
2379                 .thenReturn(mockProvider);
2380         List<ScanResult> scanResults = new ArrayList<>() {{
2381                 add(mock(ScanResult.class));
2382             }};
2383         when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
2384                 .thenReturn(PasspointMatch.HomeProvider);
2385 
2386         List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
2387 
2388         assertEquals(1, testResults.size());
2389     }
2390 
2391     /**
2392      * Verify that the ScanResults(Access Points) are not returned when it cannot be
2393      * authenticated with the provided passpoint configuration as none match.
2394      */
2395     @Test
getMatchingScanResultsTestWithNonMatch()2396     public void getMatchingScanResultsTestWithNonMatch() {
2397         PasspointConfiguration config = mock(PasspointConfiguration.class);
2398 
2399         PasspointProvider mockProvider = mock(PasspointProvider.class);
2400 
2401         when(mObjectFactory.makePasspointProvider(config, null,
2402                 mWifiCarrierInfoManager, 0, 0, null, false))
2403                 .thenReturn(mockProvider);
2404 
2405         List<ScanResult> scanResults = new ArrayList<>() {{
2406                 add(mock(ScanResult.class));
2407             }};
2408         when(mockProvider.match(anyMap(), any(RoamingConsortium.class)))
2409                 .thenReturn(PasspointMatch.None);
2410 
2411         List<ScanResult> testResults = mManager.getMatchingScanResults(config, scanResults);
2412 
2413         assertEquals(0, testResults.size());
2414     }
2415 
2416     /**
2417      * Verify that no ANQP queries are requested when not allowed (i.e. by WifiMetrics) when
2418      * there is a cache miss.
2419      */
2420     @Test
testAnqpRequestNotAllowed()2421     public void testAnqpRequestNotAllowed() {
2422         reset(mWifiConfigManager);
2423         when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(null);
2424         verify(mAnqpRequestManager, never()).requestANQPElements(any(long.class),
2425                 any(ANQPNetworkKey.class), any(boolean.class), any(NetworkDetail.HSRelease.class));
2426     }
2427 
2428     /**
2429      * Verify that removing of multiple providers with the same FQDN is done correctly.
2430      */
2431     @Test
removeAllProvidersWithSameFqdn()2432     public void removeAllProvidersWithSameFqdn() {
2433         PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2434                 TEST_PACKAGE, false, TEST_REALM);
2435         PasspointProvider provider2 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2436                 TEST_PACKAGE, false, TEST_REALM2);
2437         PasspointProvider provider3 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
2438                 TEST_PACKAGE, false, TEST_REALM3);
2439 
2440         List<PasspointProvider> providers = mUserDataSource.getProviders();
2441         assertEquals(3, providers.size());
2442         verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallation();
2443         verify(mWifiMetrics, times(3)).incrementNumPasspointProviderInstallSuccess();
2444 
2445         // Remove the provider as the creator app.
2446         assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN));
2447 
2448         verify(provider1).uninstallCertsAndKeys();
2449         verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
2450                 provider1.getWifiConfig().getKey());
2451         verify(provider2).uninstallCertsAndKeys();
2452         verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
2453                 provider2.getWifiConfig().getKey());
2454         verify(provider3).uninstallCertsAndKeys();
2455         verify(mWifiConfigManager, times(1)).removePasspointConfiguredNetwork(
2456                 provider3.getWifiConfig().getKey());
2457 
2458         verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallation();
2459         verify(mWifiMetrics, times(3)).incrementNumPasspointProviderUninstallSuccess();
2460         verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class));
2461         assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
2462 
2463         // Verify content in the data source.
2464         assertTrue(mUserDataSource.getProviders().isEmpty());
2465     }
2466 
2467     /**
2468      * Verify that adding a provider with a self signed root CA increments the metrics correctly.
2469      *
2470      * @throws Exception
2471      */
2472     @Test
verifySelfSignRootCaMetrics()2473     public void verifySelfSignRootCaMetrics() throws Exception {
2474         WifiConfiguration wifiConfig = new WifiConfiguration();
2475         wifiConfig.FQDN = TEST_FQDN;
2476         PasspointConfiguration config =
2477                 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
2478         PasspointProvider provider = createMockProvider(config, wifiConfig, true);
2479         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
2480             eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2481             eq(true))).thenReturn(provider);
2482         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
2483         assertTrue(mManager.addOrUpdateProvider(
2484                 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
2485         verify(mWifiMetrics).incrementNumPasspointProviderWithSelfSignedRootCa();
2486         verify(mWifiMetrics, never()).incrementNumPasspointProviderWithNoRootCa();
2487         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2488         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2489     }
2490 
2491     /**
2492      * Verify that adding a provider with no root CA increments the metrics correctly.
2493      *
2494      * @throws Exception
2495      */
2496     @Test
verifyNoRootCaMetrics()2497     public void verifyNoRootCaMetrics() throws Exception {
2498         WifiConfiguration wifiConfig = new WifiConfiguration();
2499         wifiConfig.FQDN = TEST_FQDN;
2500         PasspointConfiguration config =
2501                 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
2502         config.getCredential().setCaCertificate(null);
2503         PasspointProvider provider = createMockProvider(config, wifiConfig, true);
2504         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
2505             eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2506             eq(true))).thenReturn(provider);
2507         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
2508         assertTrue(mManager.addOrUpdateProvider(
2509                 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
2510         verify(mWifiMetrics).incrementNumPasspointProviderWithNoRootCa();
2511         verify(mWifiMetrics, never()).incrementNumPasspointProviderWithSelfSignedRootCa();
2512         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2513         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2514     }
2515 
2516     /**
2517      * Verify that adding a provider with subscription expiration increments the metrics correctly.
2518      *
2519      * @throws Exception
2520      */
2521     @Test
verifySubscriptionExpirationMetrics()2522     public void verifySubscriptionExpirationMetrics() throws Exception {
2523         WifiConfiguration wifiConfig = new WifiConfiguration();
2524         wifiConfig.FQDN = TEST_FQDN;
2525         PasspointConfiguration config =
2526                 createTestConfigWithUserCredential(TEST_FQDN, TEST_FRIENDLY_NAME);
2527         config.setSubscriptionExpirationTimeInMillis(1586228641000L);
2528         PasspointProvider provider = createMockProvider(config, wifiConfig, true);
2529         when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
2530             eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
2531             eq(true))).thenReturn(provider);
2532         when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
2533         assertTrue(mManager.addOrUpdateProvider(
2534                 config, TEST_CREATOR_UID, TEST_PACKAGE, true, false));
2535         verify(mWifiMetrics).incrementNumPasspointProviderWithSubscriptionExpiration();
2536         verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
2537         verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
2538     }
2539 }
2540