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