1 /*
2  * Copyright (C) 2018 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;
18 
19 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED;
20 
21 import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_EAP;
22 import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK;
23 import static com.android.server.wifi.WifiConfigurationTestUtil.generateWifiConfig;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.Mockito.any;
29 import static org.mockito.Mockito.anyBoolean;
30 import static org.mockito.Mockito.anyInt;
31 import static org.mockito.Mockito.anyString;
32 import static org.mockito.Mockito.atLeast;
33 import static org.mockito.Mockito.eq;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.never;
36 import static org.mockito.Mockito.times;
37 import static org.mockito.Mockito.verify;
38 import static org.mockito.Mockito.verifyNoMoreInteractions;
39 import static org.mockito.Mockito.when;
40 
41 import android.net.wifi.WifiConfiguration;
42 import android.net.wifi.WifiEnterpriseConfig;
43 import android.net.wifi.WifiNetworkSuggestion;
44 import android.net.wifi.WifiSsid;
45 import android.os.Process;
46 import android.telephony.SubscriptionManager;
47 import android.util.LocalLog;
48 import android.util.Pair;
49 
50 import androidx.test.filters.SmallTest;
51 
52 import com.android.modules.utils.build.SdkLevel;
53 import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
54 import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
55 import com.android.server.wifi.entitlement.PseudonymInfo;
56 
57 import org.junit.Before;
58 import org.junit.Test;
59 import org.mockito.ArgumentCaptor;
60 import org.mockito.Mock;
61 import org.mockito.MockitoAnnotations;
62 
63 import java.util.ArrayList;
64 import java.util.Arrays;
65 import java.util.Collections;
66 import java.util.HashSet;
67 import java.util.List;
68 import java.util.Optional;
69 import java.util.Set;
70 
71 /**
72  * Unit tests for {@link NetworkSuggestionNominator}.
73  */
74 @SmallTest
75 public class NetworkSuggestionNominatorTest extends WifiBaseTest {
76     private static final int TEST_UID = 3555;
77     private static final int TEST_UID_OTHER = 3545;
78     private static final int TEST_NETWORK_ID = 55;
79     private static final String TEST_PACKAGE = "com.test";
80     private static final String TEST_PACKAGE_OTHER = "com.test.other";
81     private static final String TEST_FQDN = "fqdn";
82     private static final int TEST_CARRIER_ID = 1911;
83     private static final String TEST_CARRIER_NAME = "testCarrier";
84     private static final int TEST_SUB_ID = 2020;
85     private static final String PASSPOINT_UNIQUE_ID = "uniqueId";
86 
87 
88     private @Mock WifiConfigManager mWifiConfigManager;
89     private @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
90     private @Mock Clock mClock;
91     private @Mock WifiCarrierInfoManager mWifiCarrierInfoManager;
92     private @Mock WifiPseudonymManager mWifiPseudonymManager;
93     private @Mock WifiMetrics mWifiMetrics;
94     private NetworkSuggestionNominator mNetworkSuggestionNominator;
95     private List<Pair<ScanDetail, WifiConfiguration>> mPasspointCandidates =
96             Collections.emptyList();
97 
98     /** Sets up test. */
99     @Before
setUp()100     public void setUp() throws Exception {
101         MockitoAnnotations.initMocks(this);
102         mNetworkSuggestionNominator = new NetworkSuggestionNominator(
103                 mWifiNetworkSuggestionsManager, mWifiConfigManager,
104                 new LocalLog(100), mWifiCarrierInfoManager, mWifiPseudonymManager,
105                 mWifiMetrics);
106         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(
107                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
108         when(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(anyString())).thenReturn(false);
109     }
110 
111     /**
112      * Ensure that we ignore all scan results not matching the network suggestion.
113      * Expected connectable Networks: {}
114      */
115     @Test
testSelectNetworkSuggestionForNoMatch()116     public void testSelectNetworkSuggestionForNoMatch() {
117         String[] scanSsids = {"test1", "test2"};
118         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
119         int[] freqs = {2470, 2437};
120         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
121         int[] levels = {-67, -76};
122         String[] suggestionSsids = {};
123         int[] securities = {};
124         boolean[] appInteractions = {};
125         boolean[] meteredness = {};
126         int[] priorities = {};
127         int[] uids = {};
128         String[] packageNames = {};
129         boolean[] autojoin = {};
130         boolean[] shareWithUser = {};
131         int[] priorityGroup = {};
132 
133         ScanDetail[] scanDetails =
134                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
135         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
136                 securities, appInteractions, meteredness, priorities, uids,
137                 packageNames, autojoin, shareWithUser, priorityGroup);
138         // Link the scan result with suggestions.
139         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
140 
141         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
142         mNetworkSuggestionNominator.nominateNetworks(
143                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
144                 Collections.emptySet(),
145                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
146                     connectableNetworks.add(Pair.create(scanDetail, configuration));
147                 });
148 
149         assertTrue(connectableNetworks.isEmpty());
150         verify(mWifiMetrics, never())
151                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
152     }
153 
154     /**
155      * Ensure that we nominate the only matching network suggestion.
156      * Expected connectable Networks: {suggestionSsids[0]}
157      */
158     @Test
testSelectNetworkSuggestionForOneMatch()159     public void testSelectNetworkSuggestionForOneMatch() {
160         String[] scanSsids = {"test1", "test2"};
161         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
162         int[] freqs = {2470, 2437};
163         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
164         int[] levels = {-67, -76};
165         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
166         int[] securities = {SECURITY_PSK};
167         boolean[] appInteractions = {true};
168         boolean[] meteredness = {true};
169         int[] priorities = {-1};
170         int[] uids = {TEST_UID};
171         String[] packageNames = {TEST_PACKAGE};
172         boolean[] autojoin = {true};
173         boolean[] shareWithUser = {true};
174         int[] priorityGroup = {0};
175         ScanDetail[] scanDetails =
176                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
177         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
178                 securities, appInteractions, meteredness, priorities, uids,
179                 packageNames, autojoin, shareWithUser, priorityGroup);
180         // Link the scan result with suggestions.
181         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
182         // setup config manager interactions.
183         setupAddToWifiConfigManager(suggestions[0]);
184 
185         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
186         mNetworkSuggestionNominator.nominateNetworks(
187                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
188                 Collections.emptySet(),
189                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
190                     connectableNetworks.add(Pair.create(scanDetail, configuration));
191                 });
192 
193         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
194         verify(mWifiMetrics, never())
195                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
196     }
197 
198     @Test
testSelectNetworkSuggestionForOneMatchWithInsecureEnterpriseSuggestion()199     public void testSelectNetworkSuggestionForOneMatchWithInsecureEnterpriseSuggestion() {
200         String[] scanSsids = {"test1"};
201         String[] bssids = {"6c:f3:7f:ae:8c:f3"};
202         int[] freqs = {2470};
203         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]"};
204         int[] levels = {-67};
205         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
206         int[] securities = {SECURITY_EAP};
207         boolean[] appInteractions = {true};
208         boolean[] meteredness = {true};
209         int[] priorities = {-1};
210         int[] uids = {TEST_UID};
211         String[] packageNames = {TEST_PACKAGE};
212         boolean[] autojoin = {true};
213         boolean[] shareWithUser = {true};
214         int[] priorityGroup = {0};
215 
216         ScanDetail[] scanDetails =
217                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
218         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
219                 securities, appInteractions, meteredness, priorities, uids,
220                 packageNames, autojoin, shareWithUser, priorityGroup);
221         WifiConfiguration config = suggestions[0].wns.wifiConfiguration;
222         config.enterpriseConfig.setCaPath(null);
223         // Link the scan result with suggestions.
224         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
225         // setup config manager interactions.
226         setupAddToWifiConfigManager(suggestions[0]);
227 
228         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
229         mNetworkSuggestionNominator.nominateNetworks(
230                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
231                 Collections.emptySet(),
232                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
233                     connectableNetworks.add(Pair.create(scanDetail, configuration));
234                 });
235 
236         // Verify no network is nominated.
237         assertTrue(connectableNetworks.isEmpty());
238         verify(mWifiMetrics, never())
239                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
240     }
241 
242     /**
243      * Ensure that we nominate the all network suggestion corresponding to the scan results
244      * Expected connectable Networks: {suggestionSsids[0], suggestionSsids[1]}
245      */
246     @Test
testSelectNetworkSuggestionForMultipleMatch()247     public void testSelectNetworkSuggestionForMultipleMatch() {
248         String[] scanSsids = {"test1", "test2"};
249         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
250         int[] freqs = {2470, 2437};
251         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
252         int[] levels = {-56, -45};
253         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\""};
254         int[] securities = {SECURITY_PSK, SECURITY_PSK};
255         boolean[] appInteractions = {true, true};
256         boolean[] meteredness = {true, true};
257         int[] priorities = {-1, -1};
258         int[] uids = {TEST_UID, TEST_UID};
259         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE};
260         boolean[] autojoin = {true, true};
261         boolean[] shareWithUser = {true, true};
262         int[] priorityGroup = {0, 0};
263 
264         ScanDetail[] scanDetails =
265                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
266         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
267                 securities, appInteractions, meteredness, priorities, uids,
268                 packageNames, autojoin, shareWithUser, priorityGroup);
269         // Link the scan result with suggestions.
270         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
271         // setup config manager interactions.
272         setupAddToWifiConfigManager(suggestions[0], suggestions[1]);
273 
274         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
275         mNetworkSuggestionNominator.nominateNetworks(
276                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
277                 Collections.emptySet(),
278                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
279                     connectableNetworks.add(Pair.create(scanDetail, configuration));
280                 });
281 
282         validateConnectableNetworks(connectableNetworks, scanSsids[0], scanSsids[1]);
283         verify(mWifiMetrics, never())
284                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
285     }
286 
287     /**
288      * Ensure that we nominate the network suggestion corresponding to the scan result with
289      * higest priority.
290      * Expected connectable Networks: {suggestionSsids[0]}
291      */
292     @Test
testSelectNetworkSuggestionForMultipleMatchHighPriorityWins()293     public void testSelectNetworkSuggestionForMultipleMatchHighPriorityWins() {
294         String[] scanSsids = {"test1", "test2"};
295         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
296         int[] freqs = {2470, 2437};
297         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
298         int[] levels = {-56, -45};
299         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\""};
300         int[] securities = {SECURITY_PSK, SECURITY_PSK};
301         boolean[] appInteractions = {true, true};
302         boolean[] meteredness = {true, true};
303         int[] priorities = {5, 1};
304         int[] uids = {TEST_UID, TEST_UID};
305         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE};
306         boolean[] autojoin = {true, true};
307         boolean[] shareWithUser = {true, true};
308         int[] priorityGroup = {1, 1};
309 
310         ScanDetail[] scanDetails =
311                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
312         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
313                 securities, appInteractions, meteredness, priorities, uids,
314                 packageNames, autojoin, shareWithUser, priorityGroup);
315         // Link the scan result with suggestions.
316         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
317         // setup config manager interactions.
318         setupAddToWifiConfigManager(suggestions[0], suggestions[1]);
319 
320         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
321         mNetworkSuggestionNominator.nominateNetworks(
322                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
323                 Collections.emptySet(),
324                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
325                     connectableNetworks.add(Pair.create(scanDetail, configuration));
326                 });
327 
328         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
329         verify(mWifiMetrics, never())
330                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
331     }
332 
333     /**
334      * Ensure that we nominate the network suggestion corresponding to the scan result with
335      * higest priority from each priority group within same suggestor app.
336      * Expected connectable Networks: {suggestionSsids[0], suggestionSsids[2]}
337      */
338     @Test
testSelectNetworkSuggestionForMultipleMatchHighPriorityFromEachPriorityGroupWins()339     public void testSelectNetworkSuggestionForMultipleMatchHighPriorityFromEachPriorityGroupWins() {
340         String[] scanSsids = {"test1", "test2", "test3", "test4"};
341         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "6c:f3:7f:ae:8c:f5",
342                 "6c:f3:7f:ae:8c:f6"};
343         int[] freqs = {2470, 2437, 2470, 2437};
344         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]",
345                 "[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
346         int[] levels = {-56, -45, -44, -43};
347         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\"",
348                 "\"" + scanSsids[2] + "\"", "\"" + scanSsids[3] + "\""};
349         int[] securities = {SECURITY_PSK, SECURITY_PSK, SECURITY_PSK, SECURITY_PSK};
350         boolean[] appInteractions = {true, true, true, true};
351         boolean[] meteredness = {false, false, false, false};
352         int[] priorities = {5, 4, 3, 1};
353         int[] uids = {TEST_UID, TEST_UID, TEST_UID, TEST_UID};
354         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE, TEST_PACKAGE, TEST_PACKAGE};
355         boolean[] autojoin = {true, true, true, true};
356         boolean[] shareWithUser = {true, true, true, true};
357         int[] priorityGroup = {0, 0 , 1 , 1};
358 
359         ScanDetail[] scanDetails =
360                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
361         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
362                 securities, appInteractions, meteredness, priorities, uids,
363                 packageNames, autojoin, shareWithUser, priorityGroup);
364 
365         // Link the scan result with suggestions.
366         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
367         // setup config manager interactions.
368         setupAddToWifiConfigManager(suggestions[0], suggestions[1], suggestions[2], suggestions[3]);
369 
370         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
371         mNetworkSuggestionNominator.nominateNetworks(
372                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
373                 Collections.emptySet(),
374                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
375                     connectableNetworks.add(Pair.create(scanDetail, configuration));
376                 });
377 
378         validateConnectableNetworks(connectableNetworks, scanSsids[0], scanSsids[2]);
379         verify(mWifiMetrics, never())
380                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
381     }
382 
383     /**
384      * Ensure that we nominate all profiles when multiple suggestor suggested same network.
385      *
386      * Expected connectable Networks: {suggestionSsids[0], suggestionSsids[1], suggestionSsids[2]}
387      */
388     @Test
testSelectNetworkSuggestionForMultipleMatchWithMultipleSuggestions()389     public void testSelectNetworkSuggestionForMultipleMatchWithMultipleSuggestions() {
390         String[] scanSsids = {"test1", "test2"};
391         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
392         int[] freqs = {2470, 2437};
393         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
394         int[] levels = {-23, -45};
395         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\"",
396                 "\"" + scanSsids[1] + "\""};
397         int[] securities = {SECURITY_PSK, SECURITY_PSK, SECURITY_PSK};
398         boolean[] appInteractions = {true, true, false};
399         boolean[] meteredness = {true, true, false};
400         int[] priorities = {-1, -1, -1};
401         int[] uids = {TEST_UID, TEST_UID, TEST_UID_OTHER};
402         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE, TEST_PACKAGE_OTHER};
403         boolean[] autojoin = {true, true, true};
404         boolean[] shareWithUser = {true, true, true};
405         int[] priorityGroup = {0, 0, 0};
406 
407         ScanDetail[] scanDetails =
408                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
409         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
410                 securities, appInteractions, meteredness, priorities, uids,
411                 packageNames, autojoin, shareWithUser, priorityGroup);
412         // Link the scan result with suggestions.
413         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
414         // setup config manager interactions.
415         setupAddToWifiConfigManager(suggestions[0], suggestions[1], suggestions[2]);
416 
417         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
418         mNetworkSuggestionNominator.nominateNetworks(
419                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
420                 Collections.emptySet(),
421                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
422                     connectableNetworks.add(Pair.create(scanDetail, configuration));
423                 });
424 
425         validateConnectableNetworks(connectableNetworks, scanSsids[0], scanSsids[1], scanSsids[1]);
426         verify(mWifiMetrics).incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
427     }
428 
429     /**
430      * Ensure that we nominate the network suggestion with the higest priority among network
431      * suggestions from the same package. Among different packages, nominate all the suggestion
432      * corresponding to the scan result.
433      *
434      * The suggestion[1] has higher priority than suggestion[0].
435      *
436      * Expected connectable Networks: {suggestionSsids[1],
437      *                                 (suggestionSsids[2],
438      *                                  suggestionSsids[3]}
439      */
440     @Test
441     public void
testSelectNetworkSuggestionForMultipleMatchWithMultipleSuggestionsHighPriorityWins()442             testSelectNetworkSuggestionForMultipleMatchWithMultipleSuggestionsHighPriorityWins() {
443         String[] scanSsids = {"test1", "test2", "test3", "test4"};
444         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "6c:fc:de:34:12",
445                 "6c:fd:a1:11:11:98"};
446         int[] freqs = {2470, 2437, 2470, 2437};
447         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]",
448                 "[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
449         int[] levels = {-23, -45, -56, -65};
450         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\"",
451                 "\"" + scanSsids[2] + "\"", "\"" + scanSsids[3] + "\""};
452         int[] securities = {SECURITY_PSK, SECURITY_PSK, SECURITY_PSK, SECURITY_PSK};
453         boolean[] appInteractions = {true, true, false, false};
454         boolean[] meteredness = {true, true, false, false};
455         int[] priorities = {0, 5, -1, -1};
456         int[] uids = {TEST_UID, TEST_UID, TEST_UID_OTHER, TEST_UID_OTHER};
457         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE, TEST_PACKAGE_OTHER,
458                 TEST_PACKAGE_OTHER};
459         boolean[] autojoin = {true, true, true, true};
460         boolean[] shareWithUser = {true, true, true, true};
461         int[] priorityGroup = {0, 0, 0, 0};
462 
463         ScanDetail[] scanDetails =
464                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
465         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
466                 securities, appInteractions, meteredness, priorities, uids,
467                 packageNames, autojoin, shareWithUser, priorityGroup);
468         // Link the scan result with suggestions.
469         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
470         // setup config manager interactions.
471         setupAddToWifiConfigManager(suggestions[0], suggestions[1], suggestions[2], suggestions[3]);
472 
473         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
474         mNetworkSuggestionNominator.nominateNetworks(
475                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
476                 Collections.emptySet(),
477                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
478                     connectableNetworks.add(Pair.create(scanDetail, configuration));
479                 });
480 
481         validateConnectableNetworks(connectableNetworks, scanSsids[1], scanSsids[2], scanSsids[3]);
482         verify(mWifiMetrics, never())
483                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
484     }
485 
486     /**
487      * Ensure that we nominate no candidate if the only matching network suggestion, but we failed
488      * the {@link WifiConfigManager} interactions.
489      *
490      * Expected connectable Networks: {}
491      */
492     @Test
testSelectNetworkSuggestionForOneMatchButInToWifiConfigManager()493     public void testSelectNetworkSuggestionForOneMatchButInToWifiConfigManager() {
494         String[] scanSsids = {"test1", "test2"};
495         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
496         int[] freqs = {2470, 2437};
497         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
498         int[] levels = {-67, -76};
499         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
500         int[] securities = {SECURITY_PSK};
501         boolean[] appInteractions = {true};
502         boolean[] meteredness = {true};
503         int[] priorities = {-1};
504         int[] uids = {TEST_UID};
505         String[] packageNames = {TEST_PACKAGE};
506         boolean[] autojoin = {true};
507         boolean[] shareWithUser = {true};
508         int[] priorityGroup = {1};
509 
510         ScanDetail[] scanDetails =
511                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
512         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
513                 securities, appInteractions, meteredness, priorities, uids,
514                 packageNames, autojoin, shareWithUser, priorityGroup);
515         // Link the scan result with suggestions.
516         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
517 
518         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
519         mNetworkSuggestionNominator.nominateNetworks(
520                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
521                 Collections.emptySet(),
522                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
523                     connectableNetworks.add(Pair.create(scanDetail, configuration));
524                 });
525 
526         assertTrue(connectableNetworks.isEmpty());
527 
528         verify(mWifiConfigManager).getConfiguredNetwork(eq(suggestions[0]
529                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getProfileKey()));
530         // Verify we did not try to add any new networks or other interactions with
531         // WifiConfigManager.
532         verifyNoMoreInteractions(mWifiConfigManager);
533         verify(mWifiMetrics, never())
534                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
535     }
536 
537     /**
538      * Ensure that we nominate the only matching network suggestion, but that matches an existing
539      * saved network (maybe saved or maybe it exists from a previous connection attempt) .
540      *
541      * Expected connectable Networks: {suggestionSsids[0]}
542      */
543     @Test
testSelectNetworkSuggestionForOneMatchForExistingNetwork()544     public void testSelectNetworkSuggestionForOneMatchForExistingNetwork() {
545         String[] scanSsids = {"test1", "test2"};
546         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
547         int[] freqs = {2470, 2437};
548         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
549         int[] levels = {-67, -76};
550         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
551         int[] securities = {SECURITY_PSK};
552         boolean[] appInteractions = {true};
553         boolean[] meteredness = {true};
554         int[] priorities = {-1};
555         int[] uids = {TEST_UID};
556         String[] packageNames = {TEST_PACKAGE};
557         boolean[] autojoin = {true};
558         boolean[] shareWithUser = {true};
559         int[] priorityGroup = {0};
560 
561         ScanDetail[] scanDetails =
562                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
563         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
564                 securities, appInteractions, meteredness, priorities, uids,
565                 packageNames, autojoin, shareWithUser, priorityGroup);
566         // Link the scan result with suggestions.
567         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
568         // setup config manager interactions.
569         suggestions[0].wns.wifiConfiguration.fromWifiNetworkSuggestion = true;
570         suggestions[0].wns.wifiConfiguration.ephemeral = true;
571         setupAddToWifiConfigManager(suggestions[0]);
572         // Existing saved network matching the credentials.
573         when(mWifiConfigManager.getConfiguredNetwork(suggestions[0]
574                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getKey()))
575                 .thenReturn(suggestions[0].wns.wifiConfiguration);
576 
577         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
578         mNetworkSuggestionNominator.nominateNetworks(
579                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
580                 Collections.emptySet(),
581                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
582                     connectableNetworks.add(Pair.create(scanDetail, configuration));
583                 });
584 
585         validateConnectableNetworks(connectableNetworks, new String[] {scanSsids[0]});
586 
587         // check for any saved networks.
588         verify(mWifiConfigManager, times(suggestionSsids.length))
589                 .isNetworkTemporarilyDisabledByUser(anyString());
590         verify(mWifiConfigManager).getConfiguredNetwork(suggestions[0]
591                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getProfileKey());
592         verify(mWifiConfigManager).isNonCarrierMergedNetworkTemporarilyDisabled(any());
593         if (SdkLevel.isAtLeastS()) {
594             verify(mWifiConfigManager).getConfiguredNetwork(suggestions[0]
595                     .createInternalWifiConfiguration(mWifiCarrierInfoManager).getKey());
596         }
597         // Verify we did not try to add any new networks or other interactions with
598         // WifiConfigManager.
599         verifyNoMoreInteractions(mWifiConfigManager);
600         if (SdkLevel.isAtLeastS()) {
601             verify(mWifiMetrics).addSuggestionExistsForSavedNetwork(
602                     suggestions[0].wns.wifiConfiguration.getKey());
603         }
604     }
605 
606     /**
607      * Ensure that we don't nominate the only matching network suggestion if it was previously
608      * disabled by the user.
609      *
610      * Expected connectable Networks: {}
611      */
612     @Test
testSelectNetworkSuggestionForOneMatchButUserForgotTheNetwork()613     public void testSelectNetworkSuggestionForOneMatchButUserForgotTheNetwork() {
614         String[] scanSsids = {"test1", "test2"};
615         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
616         int[] freqs = {2470, 2437};
617         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
618         int[] levels = {-67, -76};
619         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
620         int[] securities = {SECURITY_PSK};
621         boolean[] appInteractions = {true};
622         boolean[] meteredness = {true};
623         int[] priorities = {-1};
624         int[] uids = {TEST_UID};
625         String[] packageNames = {TEST_PACKAGE};
626         boolean[] autojoin = {true};
627         boolean[] shareWithUser = {true};
628         int[] priorityGroup = {0};
629 
630         ScanDetail[] scanDetails =
631                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
632         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
633                 securities, appInteractions, meteredness, priorities, uids,
634                 packageNames, autojoin, shareWithUser, priorityGroup);
635         // Link the scan result with suggestions.
636         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
637         // setup config manager interactions.
638         setupAddToWifiConfigManager(suggestions[0]);
639         // Network was disabled by the user.
640         when(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(suggestionSsids[0]))
641                 .thenReturn(true);
642 
643         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
644         mNetworkSuggestionNominator.nominateNetworks(
645                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
646                 Collections.emptySet(),
647                 (ScanDetail scanDetail, WifiConfiguration configuration) ->
648                         connectableNetworks.add(Pair.create(scanDetail, configuration)));
649 
650         assertTrue(connectableNetworks.isEmpty());
651 
652         verify(mWifiConfigManager, times(suggestionSsids.length))
653                 .isNetworkTemporarilyDisabledByUser(anyString());
654         verify(mWifiMetrics, never())
655                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
656     }
657 
658     /**
659      * Ensure that we don't nominate the only matching network suggestion if the network
660      * configuration already exists (maybe saved or maybe it exists from a previous connection
661      * attempt) and blacklisted.
662      *
663      * Expected connectable Networks: {}
664      */
665     @Test
testSelectNetworkSuggestionForOneMatchForExistingNetworkButTempDisabled()666     public void testSelectNetworkSuggestionForOneMatchForExistingNetworkButTempDisabled() {
667         String[] scanSsids = {"test1", "test2"};
668         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
669         int[] freqs = {2470, 2437};
670         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
671         int[] levels = {-67, -76};
672         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
673         int[] securities = {SECURITY_PSK};
674         boolean[] appInteractions = {true};
675         boolean[] meteredness = {true};
676         int[] priorities = {-1};
677         int[] uids = {TEST_UID};
678         String[] packageNames = {TEST_PACKAGE};
679         boolean[] autojoin = {true};
680         boolean[] shareWithUser = {true};
681         int[] priorityGroup = {0};
682 
683         ScanDetail[] scanDetails =
684                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
685         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
686                 securities, appInteractions, meteredness, priorities, uids,
687                 packageNames, autojoin, shareWithUser, priorityGroup);
688         // Link the scan result with suggestions.
689         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
690         // Mark the network disabled.
691         suggestions[0].wns.wifiConfiguration.getNetworkSelectionStatus().setNetworkSelectionStatus(
692                 NETWORK_SELECTION_TEMPORARY_DISABLED);
693         // setup config manager interactions.
694         setupAddToWifiConfigManager(suggestions[0]);
695 
696         // Existing network matching the credentials.
697         when(mWifiConfigManager.getConfiguredNetwork(suggestions[0]
698                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getProfileKey()))
699                 .thenReturn(suggestions[0].wns.wifiConfiguration);
700 
701         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
702         mNetworkSuggestionNominator.nominateNetworks(
703                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
704                 Collections.emptySet(),
705                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
706                     connectableNetworks.add(Pair.create(scanDetail, configuration));
707                 });
708 
709         assertTrue(connectableNetworks.isEmpty());
710         verify(mWifiConfigManager).getConfiguredNetwork(eq(
711                 suggestions[0].wns.wifiConfiguration.getProfileKey()));
712         verify(mWifiConfigManager).tryEnableNetwork(eq(
713                 suggestions[0].wns.wifiConfiguration.networkId));
714         if (SdkLevel.isAtLeastS()) {
715             verify(mWifiConfigManager).getConfiguredNetwork(eq(
716                     suggestions[0].wns.wifiConfiguration.getKey()));
717         }
718         // Verify we did not try to add any new networks or other interactions with
719         // WifiConfigManager.
720         verifyNoMoreInteractions(mWifiConfigManager);
721         verify(mWifiMetrics, never())
722                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
723     }
724 
725     /**
726      * Ensure that we do nominate the only matching network suggestion if the network configuration
727      * already exists (maybe saved or maybe it exists from a previous connection attempt) and a
728      * temporary blacklist expired.
729      *
730      * Expected connectable Networks: {suggestionSsids[0]}
731      */
732     @Test
testSelectNetworkSuggestionForOneMatchForExistingNetworkButTempDisableExpired()733     public void testSelectNetworkSuggestionForOneMatchForExistingNetworkButTempDisableExpired() {
734         String[] scanSsids = {"test1", "test2"};
735         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
736         int[] freqs = {2470, 2437};
737         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
738         int[] levels = {-67, -76};
739         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
740         int[] securities = {SECURITY_PSK};
741         boolean[] appInteractions = {true};
742         boolean[] meteredness = {true};
743         int[] priorities = {-1};
744         int[] uids = {TEST_UID};
745         String[] packageNames = {TEST_PACKAGE};
746         boolean[] autojoin = {true};
747         boolean[] shareWithUser = {true};
748         int[] priorityGroup = {0};
749 
750         ScanDetail[] scanDetails =
751                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
752         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
753                 securities, appInteractions, meteredness, priorities, uids,
754                 packageNames, autojoin, shareWithUser, priorityGroup);
755         // Link the scan result with suggestions.
756         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
757         // setup config manager interactions.
758         suggestions[0].wns.wifiConfiguration.fromWifiNetworkSuggestion = true;
759         suggestions[0].wns.wifiConfiguration.ephemeral = true;
760         setupAddToWifiConfigManager(suggestions[0]);
761         // Mark the network disabled.
762         suggestions[0].wns.wifiConfiguration.getNetworkSelectionStatus().setNetworkSelectionStatus(
763                 NETWORK_SELECTION_TEMPORARY_DISABLED);
764         // Existing network matching the credentials.
765         when(mWifiConfigManager.getConfiguredNetwork(suggestions[0]
766                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getProfileKey()))
767                 .thenReturn(suggestions[0].wns.wifiConfiguration);
768         when(mWifiConfigManager.tryEnableNetwork(suggestions[0].wns.wifiConfiguration.networkId))
769                 .thenReturn(true);
770 
771         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
772         mNetworkSuggestionNominator.nominateNetworks(
773                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
774                 Collections.emptySet(),
775                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
776                     connectableNetworks.add(Pair.create(scanDetail, configuration));
777                 });
778 
779         validateConnectableNetworks(connectableNetworks, new String[] {scanSsids[0]});
780 
781         verify(mWifiConfigManager, times(suggestionSsids.length))
782                 .isNetworkTemporarilyDisabledByUser(anyString());
783         verify(mWifiConfigManager).getConfiguredNetwork(eq(suggestions[0]
784                 .createInternalWifiConfiguration(mWifiCarrierInfoManager).getProfileKey()));
785         verify(mWifiConfigManager).tryEnableNetwork(eq(
786                 suggestions[0].wns.wifiConfiguration.networkId));
787         verify(mWifiConfigManager).isNonCarrierMergedNetworkTemporarilyDisabled(any());
788         if (SdkLevel.isAtLeastS()) {
789             verify(mWifiConfigManager).getConfiguredNetwork(eq(suggestions[0]
790                     .createInternalWifiConfiguration(mWifiCarrierInfoManager).getKey()));
791         }
792         // Verify we did not try to add any new networks or other interactions with
793         // WifiConfigManager.
794         verifyNoMoreInteractions(mWifiConfigManager);
795         verify(mWifiMetrics, never())
796                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
797     }
798 
799     /**
800      * Ensure that we do nominate the only matching passponit network suggestion.
801      * Expected connectable Networks: {suggestionSsids[0]}
802      */
803     @Test
testSuggestionPasspointNetworkCandidatesMatches()804     public void testSuggestionPasspointNetworkCandidatesMatches() {
805         String[] scanSsids = {"test1", "test2"};
806         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
807         int[] freqs = {2470, 2437};
808         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
809         int[] levels = {-67, -76};
810         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
811         int[] securities = {SECURITY_PSK};
812         boolean[] appInteractions = {true};
813         boolean[] meteredness = {true};
814         int[] priorities = {-1};
815         int[] uids = {TEST_UID};
816         String[] packageNames = {TEST_PACKAGE};
817         boolean[] autojoin = {true};
818         boolean[] shareWithUser = {true};
819         int[] priorityGroup = {0};
820 
821         ScanDetail[] scanDetails =
822                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
823         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
824                 securities, appInteractions, meteredness, priorities, uids, packageNames,
825                 autojoin, shareWithUser, priorityGroup);
826         HashSet<ExtendedWifiNetworkSuggestion> matchedExtSuggestions = new HashSet<>();
827         matchedExtSuggestions.add(suggestions[0]);
828         List<Pair<ScanDetail, WifiConfiguration>> passpointCandidates = new ArrayList<>();
829         suggestions[0].wns.wifiConfiguration.FQDN = TEST_FQDN;
830         suggestions[0].wns.wifiConfiguration.setPasspointUniqueId(PASSPOINT_UNIQUE_ID);
831 
832         passpointCandidates.add(Pair.create(scanDetails[0],
833                 suggestions[0].createInternalWifiConfiguration(mWifiCarrierInfoManager)));
834         when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqdn(TEST_FQDN))
835                 .thenReturn(matchedExtSuggestions);
836         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
837         mNetworkSuggestionNominator.nominateNetworks(
838                 Arrays.asList(scanDetails), passpointCandidates, false, false, false,
839                 Collections.emptySet(),
840                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
841                     connectableNetworks.add(Pair.create(scanDetail, configuration));
842                 });
843         assertEquals(1, connectableNetworks.size());
844         validateConnectableNetworks(connectableNetworks, new String[] {scanSsids[0]});
845         verify(mWifiMetrics, never())
846                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
847     }
848 
849     /**
850      * Ensure that we don't nominate the only matching passponit network suggestion when it's not
851      * approved.
852      * Expected connectable Networks: {}
853      */
854     @Test
testSuggestionPasspointNetworkCandidatesNoApprovedMatches()855     public void testSuggestionPasspointNetworkCandidatesNoApprovedMatches() {
856         String[] scanSsids = {"test1", "test2"};
857         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
858         int[] freqs = {2470, 2437};
859         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
860         int[] levels = {-67, -76};
861         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
862         int[] securities = {SECURITY_PSK};
863         boolean[] appInteractions = {true};
864         boolean[] meteredness = {true};
865         int[] priorities = {-1};
866         int[] uids = {TEST_UID};
867         String[] packageNames = {TEST_PACKAGE};
868         boolean[] autojoin = {true};
869         boolean[] shareWithUser = {true};
870         int[] priorityGroup = {0};
871 
872         ScanDetail[] scanDetails =
873                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
874         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
875                 securities, appInteractions, meteredness, priorities, uids, packageNames,
876                 autojoin, shareWithUser, priorityGroup);
877         HashSet<ExtendedWifiNetworkSuggestion> matchedExtSuggestions = new HashSet<>();
878         matchedExtSuggestions.add(suggestions[0]);
879         List<Pair<ScanDetail, WifiConfiguration>> passpointCandidates = new ArrayList<>();
880         suggestions[0].wns.wifiConfiguration.FQDN = TEST_FQDN;
881         suggestions[0].wns.wifiConfiguration.setPasspointUniqueId(PASSPOINT_UNIQUE_ID);
882 
883         passpointCandidates.add(Pair.create(scanDetails[0],
884                 suggestions[0].createInternalWifiConfiguration(mWifiCarrierInfoManager)));
885         // As user haven't approved this suggestion, return null
886         when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqdn(TEST_FQDN))
887                 .thenReturn(Set.of());
888         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
889         mNetworkSuggestionNominator.nominateNetworks(
890                 Arrays.asList(scanDetails), passpointCandidates, false, false, false,
891                 Collections.emptySet(),
892                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
893                     connectableNetworks.add(Pair.create(scanDetail, configuration));
894                 });
895         assertTrue(connectableNetworks.isEmpty());
896         verify(mWifiMetrics, never())
897                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
898     }
899 
900     /**
901      * Ensure that we will not nominate the matching network suggestions which auto-join is
902      * disabled.
903      * Expected connectable Networks: {}
904      */
905     @Test
testSelectNetworkSuggestionForOneMatchButAutojoinDisabled()906     public void testSelectNetworkSuggestionForOneMatchButAutojoinDisabled() {
907         String[] scanSsids = {"test1", "test2"};
908         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
909         int[] freqs = {2470, 2437};
910         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
911         int[] levels = {-67, -76};
912         String[] suggestionSsids = {"\"" + scanSsids[0] + "\"", "\"" + scanSsids[1] + "\""};
913         int[] securities = {SECURITY_PSK, SECURITY_PSK};
914         boolean[] appInteractions = {true, true};
915         boolean[] meteredness = {true, true};
916         int[] priorities = {-1, -1};
917         int[] uids = {TEST_UID, TEST_UID};
918         String[] packageNames = {TEST_PACKAGE, TEST_PACKAGE};
919         boolean[] autojoin = {false, false};
920         boolean[] shareWithUser = {true, false};
921         int[] priorityGroup = {0, 0};
922 
923         ScanDetail[] scanDetails =
924                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
925         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
926                 securities, appInteractions, meteredness, priorities, uids,
927                 packageNames, autojoin, shareWithUser, priorityGroup);
928         // Link the scan result with suggestions.
929         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
930         // setup config manager interactions.
931         setupAddToWifiConfigManager(suggestions[0], suggestions[1]);
932 
933         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
934         mNetworkSuggestionNominator.nominateNetworks(
935                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
936                 Collections.emptySet(),
937                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
938                     connectableNetworks.add(Pair.create(scanDetail, configuration));
939                 });
940 
941         // Verify no network is nominated.
942         assertTrue(connectableNetworks.isEmpty());
943         verify(mWifiMetrics, never())
944                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
945     }
946 
947     @Test
testSelectNetworkSuggestionForOneMatchCarrierNetworkWithNoSim()948     public void testSelectNetworkSuggestionForOneMatchCarrierNetworkWithNoSim() {
949         String[] scanSsids = {"test1"};
950         String[] bssids = {"6c:f3:7f:ae:8c:f3"};
951         int[] freqs = {2470};
952         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]"};
953         int[] levels = {-67};
954         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
955         int[] securities = {SECURITY_EAP};
956         boolean[] appInteractions = {true};
957         boolean[] meteredness = {true};
958         int[] priorities = {-1};
959         int[] uids = {TEST_UID};
960         String[] packageNames = {TEST_PACKAGE};
961         boolean[] autojoin = {true};
962         boolean[] shareWithUser = {true};
963         int[] priorityGroup = {0};
964 
965         ScanDetail[] scanDetails =
966                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
967         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
968                 securities, appInteractions, meteredness, priorities, uids,
969                 packageNames, autojoin, shareWithUser, priorityGroup);
970         suggestions[0].wns.wifiConfiguration.carrierId = TEST_CARRIER_ID;
971         when(mWifiCarrierInfoManager
972                 .getBestMatchSubscriptionId(suggestions[0].wns.wifiConfiguration))
973                 .thenReturn(TEST_SUB_ID);
974         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(false);
975         // Link the scan result with suggestions.
976         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
977         // setup config manager interactions.
978         setupAddToWifiConfigManager(suggestions[0]);
979 
980         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
981         mNetworkSuggestionNominator.nominateNetworks(
982                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
983                 Collections.emptySet(),
984                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
985                     connectableNetworks.add(Pair.create(scanDetail, configuration));
986                 });
987 
988         // Verify no network is nominated.
989         assertTrue(connectableNetworks.isEmpty());
990         verify(mWifiMetrics, never())
991                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
992     }
993 
994     @Test
testSelectNetworkSuggestionForOneMatchSimBasedWithEncryptionInfoNotAvailabele()995     public void testSelectNetworkSuggestionForOneMatchSimBasedWithEncryptionInfoNotAvailabele() {
996         String[] scanSsids = {"test1"};
997         String[] bssids = {"6c:f3:7f:ae:8c:f3"};
998         int[] freqs = {2470};
999         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]"};
1000         int[] levels = {-67};
1001         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1002         int[] securities = {SECURITY_EAP};
1003         boolean[] appInteractions = {true};
1004         boolean[] meteredness = {true};
1005         int[] priorities = {-1};
1006         int[] uids = {TEST_UID};
1007         String[] packageNames = {TEST_PACKAGE};
1008         boolean[] autojoin = {true};
1009         boolean[] shareWithUser = {true};
1010         int[] priorityGroup = {0};
1011 
1012         ScanDetail[] scanDetails =
1013                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1014         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1015                 securities, appInteractions, meteredness, priorities, uids,
1016                 packageNames, autojoin, shareWithUser, priorityGroup);
1017         WifiConfiguration eapSimConfig = suggestions[0].wns.wifiConfiguration;
1018         eapSimConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
1019         eapSimConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
1020         eapSimConfig.carrierId = TEST_CARRIER_ID;
1021         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(eapSimConfig))
1022                 .thenReturn(TEST_SUB_ID);
1023         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(true);
1024         when(mWifiCarrierInfoManager.requiresImsiEncryption(TEST_SUB_ID)).thenReturn(true);
1025         when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(TEST_SUB_ID)).thenReturn(false);
1026         // Link the scan result with suggestions.
1027         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1028         // setup config manager interactions.
1029         setupAddToWifiConfigManager(suggestions[0]);
1030 
1031         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1032         mNetworkSuggestionNominator.nominateNetworks(
1033                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1034                 Collections.emptySet(),
1035                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1036                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1037                 });
1038 
1039         // Verify no network is nominated.
1040         assertTrue(connectableNetworks.isEmpty());
1041         verify(mWifiMetrics, never())
1042                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1043     }
1044 
1045     @Test
testSelectNetworkSuggestionForOneMatchSimBasedWithOobPseudonymInfoAvailable()1046     public void testSelectNetworkSuggestionForOneMatchSimBasedWithOobPseudonymInfoAvailable() {
1047         String[] scanSsids = {"test1"};
1048         String[] bssids = {"6c:f3:7f:ae:8c:f3"};
1049         int[] freqs = {2470};
1050         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]"};
1051         int[] levels = {-67};
1052         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1053         int[] securities = {SECURITY_EAP};
1054         boolean[] appInteractions = {true};
1055         boolean[] meteredness = {true};
1056         int[] priorities = {-1};
1057         int[] uids = {TEST_UID};
1058         String[] packageNames = {TEST_PACKAGE};
1059         boolean[] autojoin = {true};
1060         boolean[] shareWithUser = {true};
1061         int[] priorityGroup = {0};
1062 
1063         ScanDetail[] scanDetails =
1064                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1065         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1066                 securities, appInteractions, meteredness, priorities, uids,
1067                 packageNames, autojoin, shareWithUser, priorityGroup);
1068         WifiConfiguration eapSimConfig = suggestions[0].wns.wifiConfiguration;
1069         eapSimConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
1070         eapSimConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
1071         eapSimConfig.carrierId = TEST_CARRIER_ID;
1072         eapSimConfig.subscriptionId = TEST_SUB_ID;
1073         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
1074         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(true);
1075         when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(anyInt(), anyBoolean()))
1076                 .thenReturn(true);
1077         when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(TEST_CARRIER_ID))
1078                 .thenReturn(true);
1079         PseudonymInfo mockPseudonymInfo = mock(PseudonymInfo.class);
1080         when(mWifiPseudonymManager.getValidPseudonymInfo(anyInt()))
1081                 .thenReturn(Optional.of(mockPseudonymInfo));
1082         // Link the scan result with suggestions.
1083         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1084         // setup config manager interactions.
1085         setupAddToWifiConfigManager(suggestions[0]);
1086 
1087         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1088         mNetworkSuggestionNominator.nominateNetworks(
1089                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1090                 Collections.emptySet(),
1091                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1092                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1093                 });
1094 
1095         verify(mWifiPseudonymManager).updateWifiConfiguration(any());
1096         assertEquals(1, connectableNetworks.size());
1097     }
1098 
1099     @Test
testSelectNetworkSuggestionForOneMatchSimBasedWithOobPseudonymIsNotAvailable()1100     public void testSelectNetworkSuggestionForOneMatchSimBasedWithOobPseudonymIsNotAvailable() {
1101         String[] scanSsids = {"test1"};
1102         String[] bssids = {"6c:f3:7f:ae:8c:f3"};
1103         int[] freqs = {2470};
1104         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]"};
1105         int[] levels = {-67};
1106         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1107         int[] securities = {SECURITY_EAP};
1108         boolean[] appInteractions = {true};
1109         boolean[] meteredness = {true};
1110         int[] priorities = {-1};
1111         int[] uids = {TEST_UID};
1112         String[] packageNames = {TEST_PACKAGE};
1113         boolean[] autojoin = {true};
1114         boolean[] shareWithUser = {true};
1115         int[] priorityGroup = {0};
1116 
1117         ScanDetail[] scanDetails =
1118                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1119         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1120                 securities, appInteractions, meteredness, priorities, uids,
1121                 packageNames, autojoin, shareWithUser, priorityGroup);
1122         WifiConfiguration eapSimConfig = suggestions[0].wns.wifiConfiguration;
1123         eapSimConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
1124         eapSimConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
1125         eapSimConfig.carrierId = TEST_CARRIER_ID;
1126         eapSimConfig.subscriptionId = TEST_SUB_ID;
1127         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
1128         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(true);
1129         when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(anyInt(), anyBoolean()))
1130                 .thenReturn(true);
1131         when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(TEST_CARRIER_ID))
1132                 .thenReturn(true);
1133         when(mWifiPseudonymManager.getValidPseudonymInfo(anyInt())).thenReturn(Optional.empty());
1134         // Link the scan result with suggestions.
1135         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1136         // setup config manager interactions.
1137         setupAddToWifiConfigManager(suggestions[0]);
1138 
1139         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1140         mNetworkSuggestionNominator.nominateNetworks(
1141                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1142                 Collections.emptySet(),
1143                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1144                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1145                 });
1146 
1147         // Verify no network is nominated.
1148         assertTrue(connectableNetworks.isEmpty());
1149         verify(mWifiPseudonymManager).retrievePseudonymOnFailureTimeoutExpired(any());
1150         verify(mWifiMetrics, never())
1151                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1152     }
1153 
1154     /**
1155      * Ensure that we nominate no matching network suggestion.
1156      * Because the only matched suggestion is untrusted and untrusted is not allowed
1157      * Expected connectable Networks: {}
1158      */
1159     @Test
testSelectNetworkSuggestionForOneMatchUntrustedNotAllow()1160     public void testSelectNetworkSuggestionForOneMatchUntrustedNotAllow() {
1161         String[] scanSsids = {"test1", "test2"};
1162         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1163         int[] freqs = {2470, 2437};
1164         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1165         int[] levels = {-67, -76};
1166         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1167         int[] securities = {SECURITY_PSK};
1168         boolean[] appInteractions = {true};
1169         boolean[] meteredness = {true};
1170         int[] priorities = {-1};
1171         int[] uids = {TEST_UID};
1172         String[] packageNames = {TEST_PACKAGE};
1173         boolean[] autojoin = {true};
1174         boolean[] shareWithUser = {true};
1175         int[] priorityGroup = {0};
1176 
1177         ScanDetail[] scanDetails =
1178                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1179         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1180                 securities, appInteractions, meteredness, priorities, uids,
1181                 packageNames, autojoin, shareWithUser, priorityGroup);
1182         suggestions[0].wns.wifiConfiguration.trusted = false;
1183         // Link the scan result with suggestions.
1184         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1185 
1186         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1187         mNetworkSuggestionNominator.nominateNetworks(
1188                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1189                 Collections.emptySet(),
1190                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1191                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1192                 });
1193 
1194         assertTrue(connectableNetworks.isEmpty());
1195         verify(mWifiMetrics, never())
1196                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1197     }
1198 
1199     /**
1200      * Ensure that we nominate the one matching network suggestion.
1201      * Because the only matched suggestion is untrusted and untrusted is allowed
1202      * Expected connectable Networks: {suggestionSsids[0]}
1203      */
1204     @Test
testSelectNetworkSuggestionForOneMatchUntrustedAllow()1205     public void testSelectNetworkSuggestionForOneMatchUntrustedAllow() {
1206         String[] scanSsids = {"test1", "test2"};
1207         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1208         int[] freqs = {2470, 2437};
1209         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1210         int[] levels = {-67, -76};
1211         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1212         int[] securities = {SECURITY_PSK};
1213         boolean[] appInteractions = {true};
1214         boolean[] meteredness = {true};
1215         int[] priorities = {-1};
1216         int[] uids = {TEST_UID};
1217         String[] packageNames = {TEST_PACKAGE};
1218         boolean[] autojoin = {true};
1219         boolean[] shareWithUser = {true};
1220         int[] priorityGroup = {0};
1221 
1222         ScanDetail[] scanDetails =
1223                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1224         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1225                 securities, appInteractions, meteredness, priorities, uids,
1226                 packageNames, autojoin, shareWithUser, priorityGroup);
1227         suggestions[0].wns.wifiConfiguration.trusted = false;
1228         // Link the scan result with suggestions.
1229         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1230 
1231         setupAddToWifiConfigManager(suggestions[0]);
1232 
1233         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1234         mNetworkSuggestionNominator.nominateNetworks(
1235                 Arrays.asList(scanDetails), mPasspointCandidates, true, false, false,
1236                 Collections.emptySet(),
1237                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1238                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1239                 });
1240 
1241         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1242         verify(mWifiMetrics, never())
1243                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1244     }
1245 
1246     /**
1247      * Ensure that we nominate no matching network suggestion.
1248      * Because the only matched suggestion is oem paid and oem paid is not allowed
1249      * Expected connectable Networks: {}
1250      */
1251     @Test
testSelectNetworkSuggestionForOneMatchOemPaidNotAllow()1252     public void testSelectNetworkSuggestionForOneMatchOemPaidNotAllow() {
1253         String[] scanSsids = {"test1", "test2"};
1254         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1255         int[] freqs = {2470, 2437};
1256         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1257         int[] levels = {-67, -76};
1258         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1259         int[] securities = {SECURITY_PSK};
1260         boolean[] appInteractions = {true};
1261         boolean[] meteredness = {true};
1262         int[] priorities = {-1};
1263         int[] uids = {TEST_UID};
1264         String[] packageNames = {TEST_PACKAGE};
1265         boolean[] autojoin = {true};
1266         boolean[] shareWithUser = {true};
1267         int[] priorityGroup = {0};
1268 
1269         ScanDetail[] scanDetails =
1270                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1271         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1272                 securities, appInteractions, meteredness, priorities, uids,
1273                 packageNames, autojoin, shareWithUser, priorityGroup);
1274         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1275         // Link the scan result with suggestions.
1276         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1277 
1278         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1279         mNetworkSuggestionNominator.nominateNetworks(
1280                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1281                 Collections.emptySet(),
1282                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1283                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1284                 });
1285 
1286         assertTrue(connectableNetworks.isEmpty());
1287         verify(mWifiMetrics, never())
1288                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1289     }
1290 
1291 
1292     /**
1293      * Ensure that we nominate the one matching network suggestion.
1294      * Because the only matched suggestion is oem paid and oem paid is allowed
1295      * Expected connectable Networks: {suggestionSsids[0]}
1296      */
1297     @Test
testSelectNetworkSuggestionForOneMatchOemPaidAllow()1298     public void testSelectNetworkSuggestionForOneMatchOemPaidAllow() {
1299         String[] scanSsids = {"test1", "test2"};
1300         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1301         int[] freqs = {2470, 2437};
1302         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1303         int[] levels = {-67, -76};
1304         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1305         int[] securities = {SECURITY_PSK};
1306         boolean[] appInteractions = {true};
1307         boolean[] meteredness = {true};
1308         int[] priorities = {-1};
1309         int[] uids = {TEST_UID};
1310         String[] packageNames = {TEST_PACKAGE};
1311         boolean[] autojoin = {true};
1312         boolean[] shareWithUser = {true};
1313         int[] priorityGroup = {0};
1314 
1315         ScanDetail[] scanDetails =
1316                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1317         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1318                 securities, appInteractions, meteredness, priorities, uids,
1319                 packageNames, autojoin, shareWithUser, priorityGroup);
1320         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1321         // Link the scan result with suggestions.
1322         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1323 
1324         setupAddToWifiConfigManager(suggestions[0]);
1325 
1326         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1327         mNetworkSuggestionNominator.nominateNetworks(
1328                 Arrays.asList(scanDetails), mPasspointCandidates, false, true, false,
1329                 Collections.emptySet(),
1330                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1331                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1332                 });
1333 
1334         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1335         verify(mWifiMetrics, never())
1336                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1337     }
1338 
1339     /**
1340      * Ensure that we nominate no matching network suggestion.
1341      * Because the only matched suggestion is oem private and oem private is not allowed
1342      * Expected connectable Networks: {}
1343      */
1344     @Test
testSelectNetworkSuggestionForOneMatchOemPrivateNotAllow()1345     public void testSelectNetworkSuggestionForOneMatchOemPrivateNotAllow() {
1346         String[] scanSsids = {"test1", "test2"};
1347         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1348         int[] freqs = {2470, 2437};
1349         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1350         int[] levels = {-67, -76};
1351         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1352         int[] securities = {SECURITY_PSK};
1353         boolean[] appInteractions = {true};
1354         boolean[] meteredness = {true};
1355         int[] priorities = {-1};
1356         int[] uids = {TEST_UID};
1357         String[] packageNames = {TEST_PACKAGE};
1358         boolean[] autojoin = {true};
1359         boolean[] shareWithUser = {true};
1360         int[] priorityGroup = {0};
1361 
1362         ScanDetail[] scanDetails =
1363                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1364         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1365                 securities, appInteractions, meteredness, priorities, uids,
1366                 packageNames, autojoin, shareWithUser, priorityGroup);
1367         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1368         // Link the scan result with suggestions.
1369         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1370 
1371         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1372         mNetworkSuggestionNominator.nominateNetworks(
1373                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1374                 Collections.emptySet(),
1375                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1376                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1377                 });
1378 
1379         assertTrue(connectableNetworks.isEmpty());
1380         verify(mWifiMetrics, never())
1381                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1382     }
1383 
1384 
1385     /**
1386      * Ensure that we nominate the one matching network suggestion.
1387      * Because the only matched suggestion is oem private and oem private is allowed
1388      * Expected connectable Networks: {suggestionSsids[0]}
1389      */
1390     @Test
testSelectNetworkSuggestionForOneMatchOemPrivateAllow()1391     public void testSelectNetworkSuggestionForOneMatchOemPrivateAllow() {
1392         String[] scanSsids = {"test1", "test2"};
1393         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1394         int[] freqs = {2470, 2437};
1395         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1396         int[] levels = {-67, -76};
1397         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1398         int[] securities = {SECURITY_PSK};
1399         boolean[] appInteractions = {true};
1400         boolean[] meteredness = {true};
1401         int[] priorities = {-1};
1402         int[] uids = {TEST_UID};
1403         String[] packageNames = {TEST_PACKAGE};
1404         boolean[] autojoin = {true};
1405         boolean[] shareWithUser = {true};
1406         int[] priorityGroup = {0};
1407 
1408         ScanDetail[] scanDetails =
1409                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1410         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1411                 securities, appInteractions, meteredness, priorities, uids,
1412                 packageNames, autojoin, shareWithUser, priorityGroup);
1413         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1414         // Link the scan result with suggestions.
1415         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1416 
1417         setupAddToWifiConfigManager(suggestions[0]);
1418 
1419         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1420         mNetworkSuggestionNominator.nominateNetworks(
1421                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, true,
1422                 Collections.emptySet(),
1423                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1424                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1425                 });
1426 
1427         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1428         verify(mWifiMetrics, never())
1429                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1430     }
1431 
1432     /**
1433      * Ensure that we nominate the one matching network suggestion.
1434      * Because the only matched suggestion has oem private & oem paid flags and both oem private and
1435      * oem paid is allowed.
1436      * Ensure that only the oemPaid flag is set in the candidate chosen to connect.
1437      * Expected connectable Networks: {suggestionSsids[0]}
1438      */
1439     @Test
1440     public void
testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAndOemPrivateAllow()1441     testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAndOemPrivateAllow() {
1442         String[] scanSsids = {"test1", "test2"};
1443         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1444         int[] freqs = {2470, 2437};
1445         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1446         int[] levels = {-67, -76};
1447         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1448         int[] securities = {SECURITY_PSK};
1449         boolean[] appInteractions = {true};
1450         boolean[] meteredness = {true};
1451         int[] priorities = {-1};
1452         int[] uids = {TEST_UID};
1453         String[] packageNames = {TEST_PACKAGE};
1454         boolean[] autojoin = {true};
1455         boolean[] shareWithUser = {true};
1456         int[] priorityGroup = {0};
1457 
1458         ScanDetail[] scanDetails =
1459                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1460         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1461                 securities, appInteractions, meteredness, priorities, uids,
1462                 packageNames, autojoin, shareWithUser, priorityGroup);
1463         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1464         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1465         // Link the scan result with suggestions.
1466         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1467 
1468         setupAddToWifiConfigManager(suggestions[0]);
1469 
1470         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1471         mNetworkSuggestionNominator.nominateNetworks(
1472                 Arrays.asList(scanDetails), mPasspointCandidates, false, true, true,
1473                 Collections.emptySet(),
1474                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1475                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1476                 });
1477 
1478         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1479         verify(mWifiMetrics, never())
1480                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1481     }
1482 
1483     /**
1484      * Ensure that we nominate no matching network suggestion.
1485      * Because the only matched suggestion has oem private & oem paid flags and both oem private and
1486      * oem paid is not allowed.
1487      * Expected connectable Networks: {}
1488      */
1489     @Test
1490     public void
testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAndOemPrivateNotAllow()1491     testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAndOemPrivateNotAllow() {
1492         String[] scanSsids = {"test1", "test2"};
1493         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1494         int[] freqs = {2470, 2437};
1495         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1496         int[] levels = {-67, -76};
1497         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1498         int[] securities = {SECURITY_PSK};
1499         boolean[] appInteractions = {true};
1500         boolean[] meteredness = {true};
1501         int[] priorities = {-1};
1502         int[] uids = {TEST_UID};
1503         String[] packageNames = {TEST_PACKAGE};
1504         boolean[] autojoin = {true};
1505         boolean[] shareWithUser = {true};
1506         int[] priorityGroup = {0};
1507 
1508         ScanDetail[] scanDetails =
1509                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1510         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1511                 securities, appInteractions, meteredness, priorities, uids,
1512                 packageNames, autojoin, shareWithUser, priorityGroup);
1513         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1514         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1515         // Link the scan result with suggestions.
1516         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1517 
1518         setupAddToWifiConfigManager(suggestions[0]);
1519 
1520         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1521         mNetworkSuggestionNominator.nominateNetworks(
1522                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1523                 Collections.emptySet(),
1524                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1525                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1526                 });
1527 
1528         assertTrue(connectableNetworks.isEmpty());
1529         verify(mWifiMetrics, never())
1530                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1531     }
1532 
1533     /**
1534      * Ensure that we nominate the one matching network suggestion.
1535      * Because the only matched suggestion has oem private & oem paid flags and only oem paid is
1536      * allowed.
1537      * Ensure that only the oemPaid flag is set in the candidate chosen to connect.
1538      * Expected connectable Networks: {suggestionSsids[0]}
1539      */
1540     @Test
1541     public void
testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAllow()1542             testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPaidAllow() {
1543         String[] scanSsids = {"test1", "test2"};
1544         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1545         int[] freqs = {2470, 2437};
1546         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1547         int[] levels = {-67, -76};
1548         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1549         int[] securities = {SECURITY_PSK};
1550         boolean[] appInteractions = {true};
1551         boolean[] meteredness = {true};
1552         int[] priorities = {-1};
1553         int[] uids = {TEST_UID};
1554         String[] packageNames = {TEST_PACKAGE};
1555         boolean[] autojoin = {true};
1556         boolean[] shareWithUser = {true};
1557         int[] priorityGroup = {0};
1558 
1559         ScanDetail[] scanDetails =
1560                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1561         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1562                 securities, appInteractions, meteredness, priorities, uids,
1563                 packageNames, autojoin, shareWithUser, priorityGroup);
1564         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1565         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1566         // Link the scan result with suggestions.
1567         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1568 
1569         setupAddToWifiConfigManager(suggestions[0]);
1570 
1571         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1572         mNetworkSuggestionNominator.nominateNetworks(
1573                 Arrays.asList(scanDetails), mPasspointCandidates, false, true, false,
1574                 Collections.emptySet(),
1575                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1576                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1577                 });
1578 
1579         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1580         verify(mWifiMetrics, never())
1581                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1582     }
1583 
1584     /**
1585      * Ensure that we nominate the one matching network suggestion.
1586      * Because the only matched suggestion has oem private & oem paid flags and only oem private is
1587      * allowed.
1588      * Ensure that only the oemPrivate flag is set in the candidate chosen to connect.
1589      * Expected connectable Networks: {suggestionSsids[0]}
1590      */
1591     @Test
1592     public void
testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPrivateAllow()1593             testSelectNetworkSuggestionForOneOemPaidAndOemPrivateMatchWithOemPrivateAllow() {
1594         String[] scanSsids = {"test1", "test2"};
1595         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1596         int[] freqs = {2470, 2437};
1597         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1598         int[] levels = {-67, -76};
1599         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1600         int[] securities = {SECURITY_PSK};
1601         boolean[] appInteractions = {true};
1602         boolean[] meteredness = {true};
1603         int[] priorities = {-1};
1604         int[] uids = {TEST_UID};
1605         String[] packageNames = {TEST_PACKAGE};
1606         boolean[] autojoin = {true};
1607         boolean[] shareWithUser = {true};
1608         int[] priorityGroup = {0};
1609 
1610         ScanDetail[] scanDetails =
1611                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1612         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1613                 securities, appInteractions, meteredness, priorities, uids,
1614                 packageNames, autojoin, shareWithUser, priorityGroup);
1615         suggestions[0].wns.wifiConfiguration.oemPaid = true;
1616         suggestions[0].wns.wifiConfiguration.oemPrivate = true;
1617         // Link the scan result with suggestions.
1618         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1619 
1620         setupAddToWifiConfigManager(suggestions[0]);
1621 
1622         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1623         mNetworkSuggestionNominator.nominateNetworks(
1624                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, true,
1625                 Collections.emptySet(),
1626                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1627                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1628                 });
1629 
1630         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1631         verify(mWifiMetrics, never())
1632                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1633     }
1634 
1635 
1636     /**
1637      * Ensure that we nominate the no matching network suggestion.
1638      * Because the only matched suggestion is metered carrier network from Non data SIM
1639      * Expected connectable Networks: {}
1640      */
1641     @Test
testSelectNetworkSuggestionForOneMatchMeteredNonDataSim()1642     public void testSelectNetworkSuggestionForOneMatchMeteredNonDataSim() {
1643         String[] scanSsids = {"test1", "test2"};
1644         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1645         int[] freqs = {2470, 2437};
1646         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1647         int[] levels = {-67, -76};
1648         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1649         int[] securities = {SECURITY_PSK};
1650         boolean[] appInteractions = {true};
1651         boolean[] meteredness = {true};
1652         int[] priorities = {-1};
1653         int[] uids = {TEST_UID};
1654         String[] packageNames = {TEST_PACKAGE};
1655         boolean[] autojoin = {true};
1656         boolean[] shareWithUser = {true};
1657         int[] priorityGroup = {0};
1658 
1659         ScanDetail[] scanDetails =
1660                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1661         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1662                 securities, appInteractions, meteredness, priorities, uids,
1663                 packageNames, autojoin, shareWithUser, priorityGroup);
1664         suggestions[0].wns.wifiConfiguration.carrierId = TEST_CARRIER_ID;
1665         suggestions[0].wns.wifiConfiguration.meteredHint = true;
1666         when(mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(any())).thenReturn(true);
1667         // Link the scan result with suggestions.
1668         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1669         setupAddToWifiConfigManager(suggestions[0]);
1670 
1671         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1672         mNetworkSuggestionNominator.nominateNetworks(
1673                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1674                 Collections.emptySet(),
1675                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1676                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1677                 });
1678 
1679         assertTrue(connectableNetworks.isEmpty());
1680         verify(mWifiMetrics, never())
1681                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1682     }
1683 
1684     /**
1685      * Ensure that we nominate the no matching network suggestion.
1686      * Because the only matched suggestion is carrier network which offloading is disabled.
1687      * Expected connectable Networks: {}
1688      */
1689     @Test
testSelectNetworkSuggestionForOneMatchCarrierOffloadDisabled()1690     public void testSelectNetworkSuggestionForOneMatchCarrierOffloadDisabled() {
1691         String[] scanSsids = {"test1", "test2"};
1692         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1693         int[] freqs = {2470, 2437};
1694         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1695         int[] levels = {-67, -76};
1696         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1697         int[] securities = {SECURITY_PSK};
1698         boolean[] appInteractions = {true};
1699         boolean[] meteredness = {true};
1700         int[] priorities = {-1};
1701         int[] uids = {TEST_UID};
1702         String[] packageNames = {TEST_PACKAGE};
1703         boolean[] autojoin = {true};
1704         boolean[] shareWithUser = {true};
1705         int[] priorityGroup = {0};
1706 
1707         ScanDetail[] scanDetails =
1708                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1709         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1710                 securities, appInteractions, meteredness, priorities, uids,
1711                 packageNames, autojoin, shareWithUser, priorityGroup);
1712         suggestions[0].wns.wifiConfiguration.carrierId = TEST_CARRIER_ID;
1713         when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(anyInt(), anyBoolean()))
1714                 .thenReturn(false);
1715         // Link the scan result with suggestions.
1716         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1717         setupAddToWifiConfigManager(suggestions[0]);
1718 
1719         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1720         mNetworkSuggestionNominator.nominateNetworks(
1721                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1722                 Collections.emptySet(),
1723                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1724                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1725                 });
1726 
1727         assertTrue(connectableNetworks.isEmpty());
1728         verify(mWifiMetrics, never())
1729                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1730     }
1731 
1732     /**
1733      * Ensure that we nominate no matching network suggestion.
1734      * Because the only matched suggestion is restricted and restricted is not allowed
1735      * Expected connectable Networks: {}
1736      */
1737     @Test
testSelectNetworkSuggestionForOneMatchRestrictedNotAllow()1738     public void testSelectNetworkSuggestionForOneMatchRestrictedNotAllow() {
1739         String[] scanSsids = {"test1", "test2"};
1740         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1741         int[] freqs = {2470, 2437};
1742         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1743         int[] levels = {-67, -76};
1744         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1745         int[] securities = {SECURITY_PSK};
1746         boolean[] appInteractions = {true};
1747         boolean[] meteredness = {true};
1748         int[] priorities = {-1};
1749         int[] uids = {TEST_UID};
1750         String[] packageNames = {TEST_PACKAGE};
1751         boolean[] autojoin = {true};
1752         boolean[] shareWithUser = {true};
1753         int[] priorityGroup = {0};
1754 
1755         ScanDetail[] scanDetails =
1756                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1757         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1758                 securities, appInteractions, meteredness, priorities, uids,
1759                 packageNames, autojoin, shareWithUser, priorityGroup);
1760         suggestions[0].wns.wifiConfiguration.restricted = true;
1761         // Link the scan result with suggestions.
1762         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1763 
1764         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1765         mNetworkSuggestionNominator.nominateNetworks(
1766                 Arrays.asList(scanDetails), mPasspointCandidates, false, false, false,
1767                 Collections.emptySet(),
1768                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1769                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1770                 });
1771 
1772         assertTrue(connectableNetworks.isEmpty());
1773         verify(mWifiMetrics, never())
1774                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1775     }
1776 
1777     /**
1778      * Ensure that we nominate the one matching network suggestion.
1779      * Because the only matched suggestion is restricted and restricted is allowed
1780      * Expected connectable Networks: {suggestionSsids[0]}
1781      */
1782     @Test
testSelectNetworkSuggestionForOneMatchRestrictedAllow()1783     public void testSelectNetworkSuggestionForOneMatchRestrictedAllow() {
1784         String[] scanSsids = {"test1", "test2"};
1785         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1786         int[] freqs = {2470, 2437};
1787         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1788         int[] levels = {-67, -76};
1789         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1790         int[] securities = {SECURITY_PSK};
1791         boolean[] appInteractions = {true};
1792         boolean[] meteredness = {true};
1793         int[] priorities = {-1};
1794         int[] uids = {TEST_UID};
1795         String[] packageNames = {TEST_PACKAGE};
1796         boolean[] autojoin = {true};
1797         boolean[] shareWithUser = {true};
1798         int[] priorityGroup = {0};
1799 
1800         ScanDetail[] scanDetails =
1801                 buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1802         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1803                 securities, appInteractions, meteredness, priorities, uids,
1804                 packageNames, autojoin, shareWithUser, priorityGroup);
1805         suggestions[0].wns.wifiConfiguration.restricted = true;
1806         // Link the scan result with suggestions.
1807         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1808 
1809         setupAddToWifiConfigManager(suggestions[0]);
1810 
1811         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1812         mNetworkSuggestionNominator.nominateNetworks(
1813                 Arrays.asList(scanDetails), mPasspointCandidates, true, false, false,
1814                 Set.of(suggestions[0].wns.wifiConfiguration.creatorUid),
1815                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1816                     connectableNetworks.add(Pair.create(scanDetail, configuration));
1817                 });
1818 
1819         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1820         verify(mWifiMetrics, never())
1821                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1822     }
1823 
1824     /**
1825      * Ensure that we nominate the one matching network suggestion.
1826      * Because the only matched suggestion is restricted and suggested by the SYSTEM_SERVER
1827      * Expected connectable Networks: {suggestionSsids[0]}
1828      */
1829     @Test
testSelectNetworkSuggestionForOneMatchRestrictedAllowBySystemServer()1830     public void testSelectNetworkSuggestionForOneMatchRestrictedAllowBySystemServer() {
1831         String[] scanSsids = {"test1", "test2"};
1832         String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1833         int[] freqs = {2470, 2437};
1834         String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
1835         int[] levels = {-67, -76};
1836         String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
1837         int[] securities = {SECURITY_PSK};
1838         boolean[] appInteractions = {true};
1839         boolean[] meteredness = {true};
1840         int[] priorities = {-1};
1841         int[] uids = {Process.SYSTEM_UID};
1842         String[] packageNames = {TEST_PACKAGE};
1843         boolean[] autojoin = {true};
1844         boolean[] shareWithUser = {true};
1845         int[] priorityGroup = {0};
1846 
1847         ScanDetail[] scanDetails =
1848             buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
1849         ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
1850             securities, appInteractions, meteredness, priorities, uids,
1851             packageNames, autojoin, shareWithUser, priorityGroup);
1852         suggestions[0].wns.wifiConfiguration.restricted = true;
1853         // Link the scan result with suggestions.
1854         linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
1855 
1856         setupAddToWifiConfigManager(suggestions[0]);
1857 
1858         List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
1859         mNetworkSuggestionNominator.nominateNetworks(
1860                 Arrays.asList(scanDetails), mPasspointCandidates, true, false, false,
1861                 Collections.emptySet(), // restrictedNetworkAllowedUids is empty
1862                 (ScanDetail scanDetail, WifiConfiguration configuration) -> {
1863                 connectableNetworks.add(Pair.create(scanDetail, configuration));
1864             });
1865 
1866         validateConnectableNetworks(connectableNetworks, scanSsids[0]);
1867         verify(mWifiMetrics, never())
1868                 .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
1869     }
1870 
setupAddToWifiConfigManager(ExtendedWifiNetworkSuggestion...candidates)1871     private void setupAddToWifiConfigManager(ExtendedWifiNetworkSuggestion...candidates) {
1872         for (int i = 0; i < candidates.length; i++) {
1873             WifiConfiguration candidate = candidates[i].createInternalWifiConfiguration(
1874                     mWifiCarrierInfoManager);
1875             WifiConfiguration.NetworkSelectionStatus status =
1876                     mock(WifiConfiguration.NetworkSelectionStatus.class);
1877             when(status.isNetworkEnabled()).thenReturn(true);
1878             candidate.setNetworkSelectionStatus(status);
1879             when(mWifiConfigManager.getConfiguredNetwork(candidate.getProfileKey()))
1880                     .thenReturn(candidate);
1881         }
1882     }
1883 
verifyAddToWifiConfigManager( boolean trustedSet, boolean oemPaidSet, boolean oemPrivateSet, WifiConfiguration...candidates)1884     private void verifyAddToWifiConfigManager(
1885             boolean trustedSet, boolean oemPaidSet, boolean oemPrivateSet,
1886             WifiConfiguration...candidates) {
1887         // check for any saved networks.
1888         verify(mWifiConfigManager, atLeast(candidates.length)).getConfiguredNetwork(anyString());
1889 
1890         ArgumentCaptor<WifiConfiguration> wifiConfigurationCaptor =
1891                 ArgumentCaptor.forClass(WifiConfiguration.class);
1892         verify(mWifiConfigManager, times(candidates.length)).addOrUpdateNetwork(
1893                 wifiConfigurationCaptor.capture(), anyInt(), anyString(), eq(false));
1894         verify(mWifiConfigManager, times(candidates.length)).allowAutojoin(anyInt(), anyBoolean());
1895         for (int i = 0; i < candidates.length; i++) {
1896             WifiConfiguration addedWifiConfiguration = null;
1897             for (WifiConfiguration configuration : wifiConfigurationCaptor.getAllValues()) {
1898                 if (configuration.SSID.equals(candidates[i].SSID)) {
1899                     addedWifiConfiguration = configuration;
1900                     break;
1901                 }
1902             }
1903             assertNotNull(addedWifiConfiguration);
1904             assertTrue(addedWifiConfiguration.ephemeral);
1905             assertTrue(addedWifiConfiguration.fromWifiNetworkSuggestion);
1906             assertEquals(trustedSet, addedWifiConfiguration.trusted);
1907             assertEquals(oemPaidSet, addedWifiConfiguration.oemPaid);
1908             assertEquals(oemPrivateSet, addedWifiConfiguration.oemPrivate);
1909         }
1910 
1911         verify(mWifiConfigManager, times(candidates.length)).updateNetworkSelectionStatus(
1912                 anyInt(), anyInt());
1913         verify(mWifiConfigManager, times(candidates.length)).getConfiguredNetwork(anyInt());
1914     }
1915 
1916     /**
1917      * Build an array of scanDetails based on the caller supplied network SSID, BSSID,
1918      * frequency, capability and RSSI level information.
1919      */
buildScanDetails(String[] ssids, String[] bssids, int[] freqs, String[] caps, int[] levels, Clock clock)1920     private static ScanDetail[] buildScanDetails(String[] ssids, String[] bssids, int[] freqs,
1921                                                     String[] caps, int[] levels, Clock clock) {
1922         if (ssids == null || ssids.length == 0) return new ScanDetail[0];
1923 
1924         ScanDetail[] scanDetails = new ScanDetail[ssids.length];
1925         long timeStamp = clock.getElapsedSinceBootMillis();
1926         for (int index = 0; index < ssids.length; index++) {
1927             scanDetails[index] = new ScanDetail(WifiSsid.fromUtf8Text(ssids[index]),
1928                     bssids[index], caps[index], levels[index], freqs[index], timeStamp, 0);
1929         }
1930         return scanDetails;
1931     }
1932 
1933     /**
1934      * Generate an array of {@link android.net.wifi.WifiConfiguration} based on the caller
1935      * supplied network SSID and security information.
1936      */
buildWifiConfigurations(String[] ssids, int[] securities)1937     private static WifiConfiguration[] buildWifiConfigurations(String[] ssids, int[] securities) {
1938         if (ssids == null || ssids.length == 0) return new WifiConfiguration[0];
1939 
1940         WifiConfiguration[] configs = new WifiConfiguration[ssids.length];
1941         for (int index = 0; index < ssids.length; index++) {
1942             configs[index] = generateWifiConfig(-1, 0, ssids[index], false, true, null,
1943                     null, securities[index]);
1944         }
1945         return configs;
1946     }
1947 
buildNetworkSuggestions( String[] ssids, int[] securities, boolean[] appInteractions, boolean[] meteredness, int[] priorities, int[] uids, String[] packageNames, boolean[] autojoin, boolean[] shareWithUser, int[] priorityGroup)1948     private ExtendedWifiNetworkSuggestion[] buildNetworkSuggestions(
1949             String[] ssids, int[] securities, boolean[] appInteractions, boolean[] meteredness,
1950             int[] priorities, int[] uids, String[] packageNames, boolean[] autojoin,
1951             boolean[] shareWithUser, int[] priorityGroup) {
1952         WifiConfiguration[] configs = buildWifiConfigurations(ssids, securities);
1953         ExtendedWifiNetworkSuggestion[] suggestions =
1954                 new ExtendedWifiNetworkSuggestion[configs.length];
1955         for (int i = 0; i < configs.length; i++) {
1956             configs[i].priority = priorities[i];
1957             configs[i].creatorUid = uids[i];
1958             configs[i].meteredOverride = meteredness[i]
1959                     ? WifiConfiguration.METERED_OVERRIDE_METERED
1960                     : WifiConfiguration.METERED_OVERRIDE_NONE;
1961             configs[i].creatorName = packageNames[i];
1962             configs[i].ephemeral = true;
1963             configs[i].fromWifiNetworkSuggestion = true;
1964             PerAppInfo perAppInfo = new PerAppInfo(uids[i], packageNames[i], null);
1965             WifiNetworkSuggestion suggestion =
1966                     new WifiNetworkSuggestion(configs[i], null, appInteractions[i], false,
1967                             shareWithUser[i], true, priorityGroup[i]);
1968             suggestions[i] = new ExtendedWifiNetworkSuggestion(suggestion, perAppInfo, autojoin[i]);
1969         }
1970         return suggestions;
1971     }
1972 
1973     /**
1974      * Link scan results to the network suggestions.
1975      *
1976      * The shorter of the 2 input params will be used to loop over so the inputs don't
1977      * need to be of equal length.
1978      * If there are more scan details than suggestions, the remaining
1979      * scan details will be associated with a NULL suggestions.
1980      * If there are more suggestions than scan details, the remaining
1981      * suggestions will be associated with the last scan detail.
1982      */
linkScanDetailsWithNetworkSuggestions( ScanDetail[] scanDetails, ExtendedWifiNetworkSuggestion[] suggestions)1983     private void linkScanDetailsWithNetworkSuggestions(
1984             ScanDetail[] scanDetails, ExtendedWifiNetworkSuggestion[] suggestions) {
1985         if (suggestions == null || scanDetails == null) {
1986             return;
1987         }
1988         int minLength = Math.min(scanDetails.length, suggestions.length);
1989 
1990         // 1 to 1 mapping from scan detail to suggestion.
1991         for (int i = 0; i < minLength; i++) {
1992             ScanDetail scanDetail = scanDetails[i];
1993             final ExtendedWifiNetworkSuggestion matchingSuggestion = suggestions[i];
1994             Set<ExtendedWifiNetworkSuggestion> matchingSuggestions = Set.of(matchingSuggestion);
1995             when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(eq(scanDetail)))
1996                     .thenReturn(matchingSuggestions);
1997         }
1998         if (scanDetails.length > suggestions.length) {
1999             // No match for the remaining scan details.
2000             for (int i = minLength; i < scanDetails.length; i++) {
2001                 ScanDetail scanDetail = scanDetails[i];
2002                 when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(
2003                         eq(scanDetail))).thenReturn(Set.of());
2004             }
2005         } else if (suggestions.length > scanDetails.length) {
2006             // All the additional suggestions match the last scan detail.
2007             HashSet<ExtendedWifiNetworkSuggestion> matchingSuggestions = new HashSet<>(
2008                     Arrays.asList(suggestions).subList(minLength - 1, suggestions.length));
2009             ScanDetail lastScanDetail = scanDetails[minLength - 1];
2010             when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(
2011                     eq(lastScanDetail))).thenReturn(matchingSuggestions);
2012         }
2013     }
2014 
validateConnectableNetworks(List<Pair<ScanDetail, WifiConfiguration>> actual, String...expectedSsids)2015     private void validateConnectableNetworks(List<Pair<ScanDetail, WifiConfiguration>> actual,
2016                                              String...expectedSsids) {
2017         assertEquals(expectedSsids.length, actual.size());
2018         Set<String> actualSsids = new HashSet<>();
2019 
2020         for (Pair<ScanDetail, WifiConfiguration> candidate : actual) {
2021             // check if the scan detail matches the wificonfiguration.
2022             assertEquals("\"" + candidate.first.getSSID() + "\"", candidate.second.SSID);
2023             actualSsids.add(candidate.first.getSSID());
2024         }
2025         // Verify actual matches the expected.
2026         assertTrue(actualSsids.containsAll(Arrays.asList(expectedSsids)));
2027     }
2028 }
2029