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.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
21 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
22 import static android.net.NetworkFactory.CMD_REQUEST_NETWORK;
23 
24 import static com.android.server.wifi.WifiNetworkFactory.PERIODIC_SCAN_INTERVAL_MS;
25 import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
26 
27 import static org.junit.Assert.*;
28 import static org.mockito.Mockito.*;
29 
30 import android.annotation.Nullable;
31 import android.app.ActivityManager;
32 import android.app.AlarmManager;
33 import android.app.AlarmManager.OnAlarmListener;
34 import android.app.AppOpsManager;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.pm.ApplicationInfo;
38 import android.content.pm.PackageManager;
39 import android.net.ConnectivityManager;
40 import android.net.MacAddress;
41 import android.net.NetworkCapabilities;
42 import android.net.NetworkProvider;
43 import android.net.NetworkRequest;
44 import android.net.wifi.INetworkRequestMatchCallback;
45 import android.net.wifi.INetworkRequestUserSelectionCallback;
46 import android.net.wifi.ScanResult;
47 import android.net.wifi.WifiConfiguration;
48 import android.net.wifi.WifiManager;
49 import android.net.wifi.WifiNetworkSpecifier;
50 import android.net.wifi.WifiScanner;
51 import android.net.wifi.WifiScanner.ScanListener;
52 import android.net.wifi.WifiScanner.ScanSettings;
53 import android.os.IBinder;
54 import android.os.Message;
55 import android.os.Messenger;
56 import android.os.PatternMatcher;
57 import android.os.Process;
58 import android.os.RemoteException;
59 import android.os.UserHandle;
60 import android.os.WorkSource;
61 import android.os.test.TestLooper;
62 import android.test.suitebuilder.annotation.SmallTest;
63 import android.util.Pair;
64 import android.util.Xml;
65 
66 import com.android.internal.util.FastXmlSerializer;
67 import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
68 import com.android.server.wifi.nano.WifiMetricsProto;
69 import com.android.server.wifi.util.ScanResultUtil;
70 import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
71 import com.android.server.wifi.util.WifiPermissionsUtil;
72 
73 import org.junit.After;
74 import org.junit.Before;
75 import org.junit.Test;
76 import org.mockito.ArgumentCaptor;
77 import org.mockito.ArgumentMatcher;
78 import org.mockito.InOrder;
79 import org.mockito.Mock;
80 import org.mockito.MockitoAnnotations;
81 import org.xmlpull.v1.XmlPullParser;
82 import org.xmlpull.v1.XmlSerializer;
83 
84 import java.io.ByteArrayInputStream;
85 import java.io.ByteArrayOutputStream;
86 import java.nio.charset.StandardCharsets;
87 import java.util.Arrays;
88 import java.util.Collections;
89 import java.util.HashMap;
90 import java.util.HashSet;
91 import java.util.LinkedHashSet;
92 import java.util.List;
93 import java.util.Map;
94 import java.util.Set;
95 
96 /**
97  * Unit tests for {@link com.android.server.wifi.WifiNetworkFactory}.
98  */
99 @SmallTest
100 public class WifiNetworkFactoryTest {
101     private static final int TEST_NETWORK_ID_1 = 104;
102     private static final int TEST_UID_1 = 10423;
103     private static final int TEST_UID_2 = 10424;
104     private static final int TEST_CALLBACK_IDENTIFIER = 123;
105     private static final String TEST_PACKAGE_NAME_1 = "com.test.networkrequest.1";
106     private static final String TEST_PACKAGE_NAME_2 = "com.test.networkrequest.2";
107     private static final String TEST_APP_NAME = "app";
108     private static final String TEST_SSID_1 = "test1234";
109     private static final String TEST_SSID_2 = "test12345678";
110     private static final String TEST_SSID_3 = "abc1234";
111     private static final String TEST_SSID_4 = "abc12345678";
112     private static final String TEST_BSSID_1 = "12:34:23:23:45:ac";
113     private static final String TEST_BSSID_2 = "12:34:23:32:12:67";
114     private static final String TEST_BSSID_3 = "45:34:34:12:bb:dd";
115     private static final String TEST_BSSID_4 = "45:34:34:56:ee:ff";
116     private static final String TEST_BSSID_1_2_OUI = "12:34:23:00:00:00";
117     private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
118     private static final String TEST_WPA_PRESHARED_KEY = "\"password123\"";
119 
120     @Mock Context mContext;
121     @Mock ActivityManager mActivityManager;
122     @Mock AlarmManager mAlarmManager;
123     @Mock AppOpsManager mAppOpsManager;
124     @Mock Clock mClock;
125     @Mock WifiInjector mWifiInjector;
126     @Mock WifiConnectivityManager mWifiConnectivityManager;
127     @Mock WifiConfigManager mWifiConfigManager;
128     @Mock WifiConfigStore mWifiConfigStore;
129     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
130     @Mock WifiScanner mWifiScanner;
131     @Mock PackageManager mPackageManager;
132     @Mock IBinder mAppBinder;
133     @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback;
134     @Mock ClientModeImpl mClientModeImpl;
135     @Mock ConnectivityManager mConnectivityManager;
136     @Mock WifiMetrics mWifiMetrics;
137     @Mock NetworkProvider mNetworkProvider;
138     NetworkCapabilities mNetworkCapabilities;
139     TestLooper mLooper;
140     NetworkRequest mNetworkRequest;
141     WifiScanner.ScanData[] mTestScanDatas;
142     WifiConfiguration mSelectedNetwork;
143     ArgumentCaptor<ScanSettings> mScanSettingsArgumentCaptor =
144             ArgumentCaptor.forClass(ScanSettings.class);
145     ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor =
146             ArgumentCaptor.forClass(WorkSource.class);
147     ArgumentCaptor<INetworkRequestUserSelectionCallback> mNetworkRequestUserSelectionCallback =
148             ArgumentCaptor.forClass(INetworkRequestUserSelectionCallback.class);
149     ArgumentCaptor<OnAlarmListener> mPeriodicScanListenerArgumentCaptor =
150             ArgumentCaptor.forClass(OnAlarmListener.class);
151     ArgumentCaptor<OnAlarmListener> mConnectionTimeoutAlarmListenerArgumentCaptor =
152             ArgumentCaptor.forClass(OnAlarmListener.class);
153     ArgumentCaptor<ScanListener> mScanListenerArgumentCaptor =
154             ArgumentCaptor.forClass(ScanListener.class);
155     InOrder mInOrder;
156 
157     private WifiNetworkFactory mWifiNetworkFactory;
158     private NetworkRequestStoreData.DataSource mDataSource;
159     private NetworkRequestStoreData mNetworkRequestStoreData;
160 
161     /**
162      * Setup the mocks.
163      */
164     @Before
setUp()165     public void setUp() throws Exception {
166         MockitoAnnotations.initMocks(this);
167 
168         mLooper = new TestLooper();
169         mNetworkCapabilities = new NetworkCapabilities();
170         mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
171         mTestScanDatas = ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 } });
172 
173         when(mContext.getPackageManager()).thenReturn(mPackageManager);
174         when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
175                 .thenReturn(mConnectivityManager);
176         when(mPackageManager.getNameForUid(TEST_UID_1)).thenReturn(TEST_PACKAGE_NAME_1);
177         when(mPackageManager.getNameForUid(TEST_UID_2)).thenReturn(TEST_PACKAGE_NAME_2);
178         when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), anyInt()))
179                 .thenReturn(new ApplicationInfo());
180         when(mPackageManager.getApplicationLabel(any())).thenReturn(TEST_APP_NAME);
181         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
182                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
183         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
184                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
185         when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
186         when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
187         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString()))
188                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID_1));
189         when(mWifiScanner.getSingleScanResults()).thenReturn(Collections.emptyList());
190 
191         mWifiNetworkFactory = new WifiNetworkFactory(mLooper.getLooper(), mContext,
192                 mNetworkCapabilities, mActivityManager, mAlarmManager, mAppOpsManager, mClock,
193                 mWifiInjector, mWifiConnectivityManager, mWifiConfigManager, mWifiConfigStore,
194                 mWifiPermissionsUtil, mWifiMetrics);
195 
196         ArgumentCaptor<NetworkRequestStoreData.DataSource> dataSourceArgumentCaptor =
197                 ArgumentCaptor.forClass(NetworkRequestStoreData.DataSource.class);
198         verify(mWifiInjector).makeNetworkRequestStoreData(dataSourceArgumentCaptor.capture());
199         mDataSource = dataSourceArgumentCaptor.getValue();
200         assertNotNull(mDataSource);
201         mNetworkRequestStoreData = new NetworkRequestStoreData(mDataSource);
202 
203         // Register factory with connectivity manager.
204         mWifiNetworkFactory.register();
205         ArgumentCaptor<NetworkProvider> networkProviderArgumentCaptor =
206                 ArgumentCaptor.forClass(NetworkProvider.class);
207         verify(mConnectivityManager).registerNetworkProvider(
208                 networkProviderArgumentCaptor.capture());
209         mNetworkProvider = networkProviderArgumentCaptor.getValue();
210         assertNotNull(mNetworkProvider);
211         mLooper.dispatchAll();
212 
213         mNetworkRequest = new NetworkRequest.Builder()
214                 .setCapabilities(mNetworkCapabilities)
215                 .build();
216 
217         // Setup with wifi on.
218         mWifiNetworkFactory.setWifiState(true);
219         mWifiNetworkFactory.enableVerboseLogging(1);
220     }
221 
222     /**
223      * Called after each test
224      */
225     @After
cleanup()226     public void cleanup() {
227         validateMockitoUsage();
228     }
229 
230     /**
231      * Validates handling of needNetworkFor.
232      */
233     @Test
testHandleNetworkRequestWithNoSpecifier()234     public void testHandleNetworkRequestWithNoSpecifier() {
235         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
236         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
237 
238         // First network request should turn on auto-join.
239         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(true);
240         assertTrue(mWifiNetworkFactory.hasConnectionRequests());
241 
242         // Subsequent ones should do nothing.
243         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
244         verifyNoMoreInteractions(mWifiConnectivityManager);
245     }
246 
247     /**
248      * Validates handling of releaseNetwork.
249      */
250     @Test
testHandleNetworkReleaseWithNoSpecifier()251     public void testHandleNetworkReleaseWithNoSpecifier() {
252         // Release network with out a corresponding request should be ignored.
253         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
254         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
255 
256         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
257         assertTrue(mWifiNetworkFactory.hasConnectionRequests());
258         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(true);
259 
260         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
261         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
262         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(false);
263     }
264 
265     /**
266      * Validates handling of acceptNetwork for requests with no network specifier.
267      */
268     @Test
testHandleAcceptNetworkRequestWithNoSpecifier()269     public void testHandleAcceptNetworkRequestWithNoSpecifier() {
270         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
271     }
272 
273     /**
274      * Validates handling of acceptNetwork with a network specifier with invalid uid/package name.
275      */
276     @Test
testHandleAcceptNetworkRequestFromWithInvalidSpecifier()277     public void testHandleAcceptNetworkRequestFromWithInvalidSpecifier() throws Exception {
278         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
279                 .thenReturn(IMPORTANCE_GONE);
280         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1))
281                 .thenReturn(true);
282         doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
283 
284         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
285         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
286 
287         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
288         mLooper.dispatchAll();
289         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
290     }
291 
292     /**
293      * Validates handling of acceptNetwork with a network specifier with internet capability.
294      */
295     @Test
testHandleAcceptNetworkRequestFromWithInternetCapability()296     public void testHandleAcceptNetworkRequestFromWithInternetCapability() throws Exception {
297         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
298                 .thenReturn(IMPORTANCE_FOREGROUND);
299 
300         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
301         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
302         mNetworkRequest.networkCapabilities.addCapability(
303                 NetworkCapabilities.NET_CAPABILITY_INTERNET);
304 
305         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
306         mLooper.dispatchAll();
307         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
308     }
309 
310     /**
311      * Validates handling of acceptNetwork with a network specifier from a non foreground
312      * app/service.
313      */
314     @Test
testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier()315     public void testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier() throws Exception {
316         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
317                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE + 1);
318 
319         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
320         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
321 
322         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
323         mLooper.dispatchAll();
324         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
325     }
326 
327     /**
328      * Validates handling of acceptNetwork with a network specifier from a foreground
329      * app.
330      */
331     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifier()332     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifier() {
333         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
334                 .thenReturn(IMPORTANCE_FOREGROUND);
335 
336         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
337         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
338 
339         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
340     }
341 
342     /**
343      * Validates handling of acceptNetwork with a network specifier from apps holding
344      * NETWORK_SETTINGS.
345      */
346     @Test
testHandleAcceptNetworkRequestFromNetworkSettingAppWithSpecifier()347     public void testHandleAcceptNetworkRequestFromNetworkSettingAppWithSpecifier() {
348         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
349                 .thenReturn(IMPORTANCE_GONE);
350         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1))
351                 .thenReturn(true);
352 
353         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
354         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
355 
356         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
357     }
358 
359     /**
360      * Validates handling of acceptNetwork with a network specifier from a foreground
361      * app.
362      */
363     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgSvc()364     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgSvc() {
365         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
366                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
367         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
368                 .thenReturn(IMPORTANCE_FOREGROUND);
369 
370         // Handle request 1.
371         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
372         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
373         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
374 
375         // Make request 2 which will be accepted because a fg app request can
376         // override a fg service request.
377         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
378         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
379         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
380     }
381 
382     /**
383      * Validates handling of acceptNetwork with a network specifier from a foreground
384      * app.
385      */
386     @Test
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc()387     public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc() {
388         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
389                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
390         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
391                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
392 
393         // Handle request 1.
394         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
395         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
396         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
397 
398         // Make request 2 which will be accepted because a fg service request can
399         // override an existing fg service request.
400         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
401         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
402         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
403     }
404 
405     /**
406      * Validates handling of acceptNetwork with a network specifier from a foreground
407      * app.
408      */
409     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgApp()410     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgApp() {
411         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
412                 .thenReturn(IMPORTANCE_FOREGROUND);
413         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
414                 .thenReturn(IMPORTANCE_FOREGROUND);
415 
416         // Handle request 1.
417         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
418         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
419         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
420 
421         // Make request 2 which will be accepted because a fg app request can
422         // override an existing fg app request.
423         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
424         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
425         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
426     }
427 
428     /**
429      * Validates handling of acceptNetwork with a network specifier from a foreground
430      * service when we're in the midst of processing a request from a foreground app.
431      */
432     @Test
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgApp()433     public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgApp()
434             throws Exception {
435         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
436                 .thenReturn(IMPORTANCE_FOREGROUND);
437         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
438                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
439 
440         // Handle request 1.
441         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
442         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
443         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
444 
445         // Make request 2 which will be rejected because a fg service request cannot
446         // override a fg app request.
447         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
448         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
449         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
450         mLooper.dispatchAll();
451         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
452     }
453 
454     /**
455      * Validates handling of acceptNetwork with a network specifier from a foreground
456      * app when we're connected to a request from a foreground app.
457      */
458     @Test
459     public void
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithConnectedRequestFromFgApp()460             testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithConnectedRequestFromFgApp()
461             throws Exception {
462         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
463                 .thenReturn(IMPORTANCE_FOREGROUND);
464         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
465                 .thenReturn(IMPORTANCE_FOREGROUND);
466 
467         // Connect to request 1
468         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
469         // Send network connection success indication.
470         assertNotNull(mSelectedNetwork);
471         mWifiNetworkFactory.handleConnectionAttemptEnded(
472                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
473 
474         // Make request 2 which will be accepted because a fg app request can
475         // override an existing fg app request.
476         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
477         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
478         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
479     }
480 
481     /**
482      * Validates handling of acceptNetwork with a network specifier from a foreground
483      * service when we're connected to a request from a foreground app.
484      */
485     @Test
486     public void
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithConnectedRequestFromFgApp()487             testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithConnectedRequestFromFgApp()
488             throws Exception {
489         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
490                 .thenReturn(IMPORTANCE_FOREGROUND);
491         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
492                 .thenReturn(IMPORTANCE_FOREGROUND_SERVICE);
493 
494         // Connect to request 1
495         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
496         // Send network connection success indication.
497         assertNotNull(mSelectedNetwork);
498         mWifiNetworkFactory.handleConnectionAttemptEnded(
499                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
500 
501         // Make request 2 which will be rejected because a fg service request cannot
502         // override a fg app request.
503         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
504         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
505         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
506         mLooper.dispatchAll();
507         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
508     }
509 
510     /**
511      * Verify handling of new network request with network specifier.
512      */
513     @Test
testHandleNetworkRequestWithSpecifier()514     public void testHandleNetworkRequestWithSpecifier() {
515         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
516         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
517         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
518 
519         // Verify UI start.
520         validateUiStartParams(true);
521 
522         // Verify scan settings.
523         verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(),
524                 mWorkSourceArgumentCaptor.capture());
525         validateScanSettings(null);
526 
527         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
528     }
529 
530     /**
531      * Validates handling of new network request with network specifier with internet capability.
532      */
533     @Test
testHandleNetworkRequestWithSpecifierAndInternetCapability()534     public void testHandleNetworkRequestWithSpecifierAndInternetCapability() throws Exception {
535         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
536         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
537         mNetworkRequest.networkCapabilities.addCapability(
538                 NetworkCapabilities.NET_CAPABILITY_INTERNET);
539 
540         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
541         mLooper.dispatchAll();
542         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
543     }
544 
545     /**
546      * Verify handling of new network request with network specifier for a hidden network.
547      */
548     @Test
testHandleNetworkRequestWithSpecifierForHiddenNetwork()549     public void testHandleNetworkRequestWithSpecifierForHiddenNetwork() {
550         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, true);
551         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
552         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
553 
554         // Verify UI start.
555         validateUiStartParams(true);
556 
557         // Verify scan settings.
558         verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(),
559                 mWorkSourceArgumentCaptor.capture());
560         validateScanSettings(specifier.ssidPatternMatcher.getPath());
561 
562         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
563     }
564 
565     /**
566      * Verify handling of new network request with network specifier for a non-hidden network
567      * after processing a previous hidden network requst.
568      * Validates that the scan settings was properly reset between the 2 request
569      * {@link ScanSettings#hiddenNetworks}
570      */
571     @Test
testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest()572     public void testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest() {
573         // Hidden request 1.
574         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, true);
575         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
576         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
577         // Verify scan settings.
578         verify(mWifiScanner, times(1)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
579                 mWorkSourceArgumentCaptor.capture());
580         validateScanSettings(specifier.ssidPatternMatcher.getPath());
581 
582         // Release request 1.
583         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
584 
585         // Regular request 2.
586         specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
587         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
588         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
589         // Verify scan settings.
590         verify(mWifiScanner, times(2)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
591                 mWorkSourceArgumentCaptor.capture());
592         validateScanSettings(null);
593 
594         verify(mWifiMetrics, times(2)).incrementNetworkRequestApiNumRequest();
595     }
596 
597     /**
598      * Verify handling of release of the active network request with network specifier.
599      */
600     @Test
testHandleNetworkReleaseWithSpecifier()601     public void testHandleNetworkReleaseWithSpecifier() {
602         // Make a generic request first to ensure that we re-enable auto-join after release.
603         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
604 
605         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
606         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
607 
608         // Make the network request with specifier.
609         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
610         verify(mWifiScanner).startScan(any(), any(), any());
611 
612         // Release the network request.
613         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
614         // Verify that we did not trigger a disconnect because we've not yet connected.
615         verify(mClientModeImpl, never()).disconnectCommand();
616         // Re-enable connectivity manager .
617         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
618 
619         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
620     }
621 
622     /**
623      * Verify the periodic scan to find a network matching the network specifier.
624      * Simulates the case where the network is not found in any of the scan results.
625      */
626     @Test
testPeriodicScanNetworkRequestWithSpecifier()627     public void testPeriodicScanNetworkRequestWithSpecifier() {
628         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
629         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
630         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
631 
632         verifyPeriodicScans(0,
633                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
634                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
635                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
636                 PERIODIC_SCAN_INTERVAL_MS);    // 10s
637     }
638 
639     /**
640      * Verify the periodic scan back off to find a network matching the network specifier
641      * is cancelled when the active network request is released.
642      */
643     @Test
testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier()644     public void testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier() {
645         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
646         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
647         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
648 
649         verifyPeriodicScans(0,
650                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
651                 PERIODIC_SCAN_INTERVAL_MS);    // 10s
652 
653         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
654         // Cancel the alarm set for the next scan.
655         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
656     }
657 
658     /**
659      * Verify callback registration/unregistration.
660      */
661     @Test
testHandleCallbackRegistrationAndUnregistration()662     public void testHandleCallbackRegistrationAndUnregistration() throws Exception {
663         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
664         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
665         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
666 
667         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
668                 TEST_CALLBACK_IDENTIFIER);
669 
670         //Ensure that we register the user selection callback using the newly registered callback.
671         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
672                 any(INetworkRequestUserSelectionCallback.class));
673 
674         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
675 
676         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
677     }
678 
679     /**
680      * Verify callback registration when the active request has already been released..
681      */
682     @Test
testHandleCallbackRegistrationWithNoActiveRequest()683     public void testHandleCallbackRegistrationWithNoActiveRequest() throws Exception {
684         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
685         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
686         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
687         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
688 
689         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
690                 TEST_CALLBACK_IDENTIFIER);
691 
692         //Ensure that we trigger the onAbort callback & nothing else.
693         verify(mNetworkRequestMatchCallback).onAbort();
694 
695         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
696 
697         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
698     }
699 
700     /**
701      * Verify network specifier matching for a specifier containing a specific SSID match using
702      * 4 WPA_PSK scan results, each with unique SSID.
703      */
704     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatch()705     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatch() throws Exception {
706         // Setup scan data for open networks.
707         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
708                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
709 
710         // Setup network specifier for open networks.
711         PatternMatcher ssidPatternMatch =
712                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
713         Pair<MacAddress, MacAddress> bssidPatternMatch =
714                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
715         WifiConfiguration wifiConfiguration = new WifiConfiguration();
716         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
717         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
718                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
719                 TEST_PACKAGE_NAME_1);
720 
721         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
722         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
723 
724         validateUiStartParams(true);
725 
726         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
727                 TEST_CALLBACK_IDENTIFIER);
728 
729         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
730 
731         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
732                 ArgumentCaptor.forClass(List.class);
733         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
734 
735         assertNotNull(matchedScanResultsCaptor.getValue());
736         // We only expect 1 network match in this case.
737         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
738 
739         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
740                 matchedScanResultsCaptor.getValue().size());
741     }
742 
743     /**
744      * Verify network specifier matching for a specifier containing a Prefix SSID match using
745      * 4 open scan results, each with unique SSID.
746      */
747     @Test
testNetworkSpecifierMatchSuccessUsingPrefixSsidMatch()748     public void testNetworkSpecifierMatchSuccessUsingPrefixSsidMatch() throws Exception {
749         // Setup scan data for open networks.
750         setupScanData(SCAN_RESULT_TYPE_OPEN,
751                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
752 
753         // Setup network specifier for open networks.
754         PatternMatcher ssidPatternMatch =
755                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX);
756         Pair<MacAddress, MacAddress> bssidPatternMatch =
757                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
758         WifiConfiguration wifiConfiguration = new WifiConfiguration();
759         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
760         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
761                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
762                 TEST_PACKAGE_NAME_1);
763 
764         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
765         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
766 
767         validateUiStartParams(false);
768 
769         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
770                 TEST_CALLBACK_IDENTIFIER);
771 
772         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
773 
774         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
775                 ArgumentCaptor.forClass(List.class);
776         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
777 
778         assertNotNull(matchedScanResultsCaptor.getValue());
779         // We expect 2 scan result matches in this case.
780         validateScanResults(matchedScanResultsCaptor.getValue(),
781                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1]);
782 
783         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
784                 matchedScanResultsCaptor.getValue().size());
785     }
786 
787     /**
788      * Verify network specifier matching for a specifier containing a specific BSSID match using
789      * 4 WPA_PSK scan results, each with unique SSID.
790      */
791     @Test
testNetworkSpecifierMatchSuccessUsingLiteralBssidMatch()792     public void testNetworkSpecifierMatchSuccessUsingLiteralBssidMatch() throws Exception {
793         // Setup scan data for open networks.
794         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
795                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
796 
797         // Setup network specifier for open networks.
798         PatternMatcher ssidPatternMatch =
799                 new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
800         Pair<MacAddress, MacAddress> bssidPatternMatch =
801                 Pair.create(MacAddress.fromString(TEST_BSSID_1), MacAddress.BROADCAST_ADDRESS);
802         WifiConfiguration wifiConfiguration = new WifiConfiguration();
803         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
804         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
805                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
806                 TEST_PACKAGE_NAME_1);
807 
808         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
809         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
810 
811         validateUiStartParams(true);
812 
813         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
814                 TEST_CALLBACK_IDENTIFIER);
815 
816         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
817 
818         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
819                 ArgumentCaptor.forClass(List.class);
820         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
821 
822         assertNotNull(matchedScanResultsCaptor.getValue());
823         // We only expect 1 scan result match in this case.
824         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
825 
826         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
827                 matchedScanResultsCaptor.getValue().size());
828     }
829 
830     /**
831      * Verify network specifier matching for a specifier containing a prefix BSSID match using
832      * 4 WPA_EAP scan results, each with unique SSID.
833      */
834     @Test
testNetworkSpecifierMatchSuccessUsingOuiPrefixBssidMatch()835     public void testNetworkSpecifierMatchSuccessUsingOuiPrefixBssidMatch() throws Exception {
836         // Setup scan data for open networks.
837         setupScanData(SCAN_RESULT_TYPE_WPA_EAP,
838                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
839 
840         // Setup network specifier for open networks.
841         PatternMatcher ssidPatternMatch =
842                 new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
843         Pair<MacAddress, MacAddress> bssidPatternMatch =
844                 Pair.create(MacAddress.fromString(TEST_BSSID_1_2_OUI),
845                         MacAddress.fromString(TEST_BSSID_OUI_MASK));
846         WifiConfiguration wifiConfiguration = new WifiConfiguration();
847         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
848         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
849                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
850                 TEST_PACKAGE_NAME_1);
851 
852         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
853         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
854 
855         validateUiStartParams(false);
856 
857         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
858                 TEST_CALLBACK_IDENTIFIER);
859 
860         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
861 
862         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
863                 ArgumentCaptor.forClass(List.class);
864         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
865 
866         assertNotNull(matchedScanResultsCaptor.getValue());
867         // We expect 2 scan result matches in this case.
868         validateScanResults(matchedScanResultsCaptor.getValue(),
869                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1]);
870 
871         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
872                 matchedScanResultsCaptor.getValue().size());
873     }
874 
875     /**
876      * Verify network specifier matching for a specifier containing a specific SSID match using
877      * 4 WPA_PSK scan results, 3 of which have the same SSID.
878      */
879     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchWithMultipleBssidMatches()880     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchWithMultipleBssidMatches()
881             throws Exception {
882         // Setup scan data for open networks.
883         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
884                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_1, TEST_SSID_2);
885 
886         // Setup network specifier for open networks.
887         PatternMatcher ssidPatternMatch =
888                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
889         Pair<MacAddress, MacAddress> bssidPatternMatch =
890                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
891         WifiConfiguration wifiConfiguration = new WifiConfiguration();
892         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
893         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
894                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
895                 TEST_PACKAGE_NAME_1);
896 
897         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
898         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
899 
900         validateUiStartParams(true);
901 
902         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
903                 TEST_CALLBACK_IDENTIFIER);
904 
905         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
906 
907         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
908                 ArgumentCaptor.forClass(List.class);
909         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
910 
911         assertNotNull(matchedScanResultsCaptor.getValue());
912         // We expect 3 scan result matches in this case.
913         validateScanResults(matchedScanResultsCaptor.getValue(),
914                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1],
915                 mTestScanDatas[0].getResults()[2]);
916 
917         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
918                 matchedScanResultsCaptor.getValue().size());
919     }
920 
921     /**
922      * Verify network specifier match failure for a specifier containing a specific SSID match using
923      * 4 WPA_PSK scan results, 2 of which SSID_1 and the other 2 SSID_2. But, none of the scan
924      * results' SSID match the one requested in the specifier.
925      */
926     @Test
testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenSsidNotFound()927     public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenSsidNotFound()
928             throws Exception {
929         // Setup scan data for open networks.
930         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
931                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_2, TEST_SSID_2);
932 
933         // Setup network specifier for open networks.
934         PatternMatcher ssidPatternMatch =
935                 new PatternMatcher(TEST_SSID_3, PatternMatcher.PATTERN_LITERAL);
936         Pair<MacAddress, MacAddress> bssidPatternMatch =
937                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
938         WifiConfiguration wifiConfiguration = new WifiConfiguration();
939         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
940         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
941                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
942                 TEST_PACKAGE_NAME_1);
943 
944         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
945         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
946 
947         validateUiStartParams(true);
948 
949         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
950                 TEST_CALLBACK_IDENTIFIER);
951 
952         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
953 
954         // We expect no network match in this case.
955         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
956 
957         // Don't increment metrics until we have a match
958         verify(mWifiMetrics, never()).incrementNetworkRequestApiMatchSizeHistogram(anyInt());
959     }
960 
961     /**
962      * Verify network specifier match failure for a specifier containing a specific SSID match using
963      * 4 open scan results, each with unique SSID. But, none of the scan
964      * results' key mgmt match the one requested in the specifier.
965      */
966     @Test
testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenKeyMgmtDiffers()967     public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenKeyMgmtDiffers()
968             throws Exception {
969         // Setup scan data for open networks.
970         setupScanData(SCAN_RESULT_TYPE_OPEN,
971                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
972 
973         // Setup network specifier for open networks.
974         PatternMatcher ssidPatternMatch =
975                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
976         Pair<MacAddress, MacAddress> bssidPatternMatch =
977                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
978         WifiConfiguration wifiConfiguration = new WifiConfiguration();
979         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
980         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
981                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
982                 TEST_PACKAGE_NAME_1);
983 
984         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
985         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
986 
987         validateUiStartParams(true);
988 
989         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
990                 TEST_CALLBACK_IDENTIFIER);
991 
992         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
993 
994         // We expect no network match in this case.
995         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
996     }
997 
998     /**
999      * Verify handling of stale user selection (previous request released).
1000      */
1001     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkWithoutActiveRequest()1002     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkWithoutActiveRequest()
1003             throws Exception {
1004         sendNetworkRequestAndSetupForUserSelection();
1005 
1006         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1007                 mNetworkRequestUserSelectionCallback.getValue();
1008         assertNotNull(networkRequestUserSelectionCallback);
1009 
1010         // Now release the active network request.
1011         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1012         // Re-enable connectivity manager (if it was disabled).
1013         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1014 
1015         // Now trigger user selection to some network.
1016         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1017         networkRequestUserSelectionCallback.select(selectedNetwork);
1018         mLooper.dispatchAll();
1019 
1020         // Verify we did not attempt to trigger a connection or disable connectivity manager.
1021         verifyNoMoreInteractions(mClientModeImpl, mWifiConnectivityManager);
1022     }
1023 
1024     /**
1025      * Verify handling of stale user selection (new request replacing the previous request).
1026      */
1027     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkWithDifferentActiveRequest()1028     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkWithDifferentActiveRequest()
1029             throws Exception {
1030         sendNetworkRequestAndSetupForUserSelection();
1031 
1032         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1033                 mNetworkRequestUserSelectionCallback.getValue();
1034         assertNotNull(networkRequestUserSelectionCallback);
1035 
1036         // Now send another network request.
1037         mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest), 0);
1038 
1039         // Now trigger user selection to some network.
1040         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1041         networkRequestUserSelectionCallback.select(selectedNetwork);
1042         mLooper.dispatchAll();
1043 
1044         // Verify we did not attempt to trigger a connection or disable connectivity manager.
1045         verifyNoMoreInteractions(mClientModeImpl, mWifiConnectivityManager, mWifiConfigManager);
1046     }
1047 
1048     /**
1049      * Verify handling of user selection to trigger connection to a network.
1050      */
1051     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetwork()1052     public void testNetworkSpecifierHandleUserSelectionConnectToNetwork() throws Exception {
1053         sendNetworkRequestAndSetupForUserSelection();
1054 
1055         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1056                 mNetworkRequestUserSelectionCallback.getValue();
1057         assertNotNull(networkRequestUserSelectionCallback);
1058 
1059         // Now trigger user selection to one of the network.
1060         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
1061         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1062         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1063         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1064         mLooper.dispatchAll();
1065 
1066         // Cancel periodic scans.
1067         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1068         // Disable connectivity manager
1069         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1070 
1071         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1072         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1073                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1074 
1075         verify(mClientModeImpl).disconnectCommand();
1076         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
1077         verify(mClientModeImpl).sendMessage(messageCaptor.capture());
1078 
1079         Message message = messageCaptor.getValue();
1080         assertNotNull(message);
1081 
1082         assertEquals(WifiManager.CONNECT_NETWORK, message.what);
1083         assertEquals(TEST_NETWORK_ID_1, message.arg1);
1084     }
1085 
1086     /**
1087      * Verify when number of user approved access points exceed the capacity, framework should trim
1088      * the Set by removing the least recently used elements.
1089      */
1090     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkExceedApprovedListCapacity()1091     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkExceedApprovedListCapacity()
1092             throws Exception {
1093         int userApproveAccessPointCapacity = mWifiNetworkFactory.NUM_OF_ACCESS_POINT_LIMIT_PER_APP;
1094         int numOfApPerSsid = userApproveAccessPointCapacity / 2 + 1;
1095         String[] testIds = new String[]{TEST_SSID_1, TEST_SSID_2};
1096 
1097         // Setup up scan data
1098         setupScanDataSameSsidWithDiffBssid(SCAN_RESULT_TYPE_WPA_PSK, numOfApPerSsid, testIds);
1099 
1100         // Setup network specifier for WPA-PSK networks.
1101         PatternMatcher ssidPatternMatch =
1102                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX);
1103         Pair<MacAddress, MacAddress> bssidPatternMatch =
1104                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
1105         WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork();
1106         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1107         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
1108                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1109                 TEST_PACKAGE_NAME_1);
1110 
1111         // request network, trigger scan and get matched set.
1112         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
1113         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
1114 
1115         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
1116                 TEST_CALLBACK_IDENTIFIER);
1117         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1118                 mNetworkRequestUserSelectionCallback.capture());
1119 
1120         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1121 
1122         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1123                 mNetworkRequestUserSelectionCallback.getValue();
1124         assertNotNull(networkRequestUserSelectionCallback);
1125 
1126         // Now trigger user selection to one of the network.
1127         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1128         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1129         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1130         mLooper.dispatchAll();
1131 
1132         // Verifier num of Approved access points.
1133         assertEquals(mWifiNetworkFactory.mUserApprovedAccessPointMap
1134                 .get(TEST_PACKAGE_NAME_1).size(), numOfApPerSsid);
1135 
1136         // Now trigger user selection to another network with different SSID.
1137         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1138         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[numOfApPerSsid].SSID + "\"";
1139         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1140         mLooper.dispatchAll();
1141 
1142         // Verify triggered trim when user Approved Access Points exceed capacity.
1143         Set<AccessPoint> userApprovedAccessPoints = mWifiNetworkFactory.mUserApprovedAccessPointMap
1144                 .get(TEST_PACKAGE_NAME_1);
1145         assertEquals(userApprovedAccessPoints.size(), userApproveAccessPointCapacity);
1146         long numOfSsid1Aps = userApprovedAccessPoints
1147                 .stream()
1148                 .filter(a->a.ssid.equals(TEST_SSID_1))
1149                 .count();
1150         assertEquals(numOfSsid1Aps, userApproveAccessPointCapacity - numOfApPerSsid);
1151     }
1152 
1153     /**
1154      * Verify handling of user selection to trigger connection to an existing saved network.
1155      */
1156     @Test
testNetworkSpecifierHandleUserSelectionConnectToExistingSavedNetwork()1157     public void testNetworkSpecifierHandleUserSelectionConnectToExistingSavedNetwork()
1158             throws Exception {
1159         sendNetworkRequestAndSetupForUserSelection();
1160 
1161         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1162                 mNetworkRequestUserSelectionCallback.getValue();
1163         assertNotNull(networkRequestUserSelectionCallback);
1164 
1165         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1166         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1167 
1168         // Have a saved network with the same configuration.
1169         WifiConfiguration matchingSavedNetwork = new WifiConfiguration(mSelectedNetwork);
1170         matchingSavedNetwork.networkId = TEST_NETWORK_ID_1;
1171         when(mWifiConfigManager.getConfiguredNetwork(mSelectedNetwork.configKey()))
1172                 .thenReturn(matchingSavedNetwork);
1173 
1174         // Now trigger user selection to one of the network.
1175         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1176         mLooper.dispatchAll();
1177 
1178         // Cancel periodic scans.
1179         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1180         // Disable connectivity manager
1181         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1182 
1183         // verify we don't try to add the network to WifiConfigManager.
1184         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), anyString());
1185 
1186         verify(mClientModeImpl).disconnectCommand();
1187         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
1188         verify(mClientModeImpl).sendMessage(messageCaptor.capture());
1189 
1190         Message message = messageCaptor.getValue();
1191         assertNotNull(message);
1192 
1193         assertEquals(WifiManager.CONNECT_NETWORK, message.what);
1194         assertEquals(TEST_NETWORK_ID_1, message.arg1);
1195     }
1196 
1197     /**
1198      * Verify handling of user selection to trigger connection to a network. Ensure we fill
1199      * up the BSSID field.
1200      */
1201     @Test
1202     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkUsingLiteralSsidAndBssidMatch()1203             testNetworkSpecifierHandleUserSelectionConnectToNetworkUsingLiteralSsidAndBssidMatch()
1204             throws Exception {
1205         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1206                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1207 
1208         // Make a specific AP request.
1209         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
1210         PatternMatcher ssidPatternMatch =
1211                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1212         Pair<MacAddress, MacAddress> bssidPatternMatch =
1213                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
1214                         MacAddress.BROADCAST_ADDRESS);
1215         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1216         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
1217         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1218         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
1219                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1220                 TEST_PACKAGE_NAME_1);
1221         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
1222         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
1223         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
1224                 TEST_CALLBACK_IDENTIFIER);
1225         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1226                 mNetworkRequestUserSelectionCallback.capture());
1227         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1228 
1229         // Now trigger user selection to the network.
1230         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1231         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1232         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1233                 mNetworkRequestUserSelectionCallback.getValue();
1234         assertNotNull(networkRequestUserSelectionCallback);
1235         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1236         mLooper.dispatchAll();
1237 
1238         // Verify WifiConfiguration params.
1239         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1240         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1241                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1242 
1243         verify(mClientModeImpl).disconnectCommand();
1244         // Verify connection message.
1245         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
1246         verify(mClientModeImpl).sendMessage(messageCaptor.capture());
1247 
1248         Message message = messageCaptor.getValue();
1249         assertNotNull(message);
1250 
1251         assertEquals(WifiManager.CONNECT_NETWORK, message.what);
1252         assertEquals(TEST_NETWORK_ID_1, message.arg1);
1253     }
1254 
1255     /**
1256      * Verify handling of user selection to trigger connection to a network. Ensure we fill
1257      * up the BSSID field with scan result for highest RSSI.
1258      */
1259     @Test
1260     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkMultipleBssidMatches()1261             testNetworkSpecifierHandleUserSelectionConnectToNetworkMultipleBssidMatches()
1262             throws Exception {
1263         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1264                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_1, TEST_SSID_4);
1265 
1266         // Make a ssid pattern request which matches 3 scan results - 0, 1, 2.
1267         PatternMatcher ssidPatternMatch =
1268                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1269         Pair<MacAddress, MacAddress> bssidPatternMatch =
1270                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
1271         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1272         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
1273         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1274         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
1275                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1276                 TEST_PACKAGE_NAME_1);
1277         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
1278         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
1279         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
1280                 TEST_CALLBACK_IDENTIFIER);
1281         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1282                 mNetworkRequestUserSelectionCallback.capture());
1283         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1284 
1285         // Scan result 2 has the highest RSSI, so that should be picked.
1286         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[2];
1287 
1288         // Now trigger user selection to the network.
1289         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1290         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1291         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1292                 mNetworkRequestUserSelectionCallback.getValue();
1293         assertNotNull(networkRequestUserSelectionCallback);
1294         networkRequestUserSelectionCallback.select(mSelectedNetwork);
1295         mLooper.dispatchAll();
1296 
1297         // Verify WifiConfiguration params.
1298         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1299         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1300                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1301 
1302         verify(mClientModeImpl).disconnectCommand();
1303         // Verify connection message.
1304         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
1305         verify(mClientModeImpl).sendMessage(messageCaptor.capture());
1306 
1307         Message message = messageCaptor.getValue();
1308         assertNotNull(message);
1309 
1310         assertEquals(WifiManager.CONNECT_NETWORK, message.what);
1311         assertEquals(TEST_NETWORK_ID_1, message.arg1);
1312     }
1313 
1314     /**
1315      * Verify handling of user selection to reject the request.
1316      */
1317     @Test
testNetworkSpecifierHandleUserSelectionReject()1318     public void testNetworkSpecifierHandleUserSelectionReject() throws Exception {
1319         sendNetworkRequestAndSetupForUserSelection();
1320 
1321         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1322                 mNetworkRequestUserSelectionCallback.getValue();
1323         assertNotNull(networkRequestUserSelectionCallback);
1324 
1325         // Now trigger user rejection.
1326         networkRequestUserSelectionCallback.reject();
1327         mLooper.dispatchAll();
1328 
1329         // Cancel periodic scans.
1330         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1331         // Verify we reset the network request handling.
1332         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1333         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1334 
1335         verify(mWifiMetrics).incrementNetworkRequestApiNumUserReject();
1336 
1337         // Verify we did not attempt to trigger a connection.
1338         verifyNoMoreInteractions(mClientModeImpl, mWifiConfigManager);
1339     }
1340 
1341     /**
1342      * Verify handling of connection timeout.
1343      * The timeouts should trigger connection retries until we hit the max.
1344      */
1345     @Test
testNetworkSpecifierHandleConnectionTimeout()1346     public void testNetworkSpecifierHandleConnectionTimeout() throws Exception {
1347         sendNetworkRequestAndSetupForConnectionStatus();
1348 
1349         // Simulate connection timeout beyond the retry limit to trigger the failure handling.
1350         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1351             mConnectionTimeoutAlarmListenerArgumentCaptor.getValue().onAlarm();
1352             mLooper.dispatchAll();
1353         }
1354 
1355         mInOrder = inOrder(mAlarmManager, mClientModeImpl);
1356         validateConnectionRetryAttempts();
1357 
1358         // Fail the request after all the retries are exhausted.
1359         verify(mNetworkRequestMatchCallback).onAbort();
1360         // Verify that we sent the connection failure callback.
1361         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1362                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1363         // Verify we reset the network request handling.
1364         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1365         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1366     }
1367 
1368     /**
1369      * Verify handling of connection trigger failure.
1370      * The trigger failures should trigger connection retries until we hit the max.
1371      */
1372     @Test
testNetworkSpecifierHandleConnectionTriggerFailure()1373     public void testNetworkSpecifierHandleConnectionTriggerFailure() throws Exception {
1374         Messenger replyToMsgr = sendNetworkRequestAndSetupForConnectionStatus();
1375 
1376         // Send failure message beyond the retry limit to trigger the failure handling.
1377         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1378             Message failureMsg = Message.obtain();
1379             failureMsg.what = WifiManager.CONNECT_NETWORK_FAILED;
1380             replyToMsgr.send(failureMsg);
1381             mLooper.dispatchAll();
1382         }
1383 
1384         mInOrder = inOrder(mAlarmManager, mClientModeImpl);
1385         validateConnectionRetryAttempts();
1386 
1387         // Fail the request after all the retries are exhausted.
1388         verify(mNetworkRequestMatchCallback).onAbort();
1389         // Verify that we sent the connection failure callback.
1390         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1391                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1392         // verify we canceled the timeout alarm.
1393         mInOrder.verify(mAlarmManager).cancel(
1394                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1395         // Verify we reset the network request handling.
1396         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1397         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1398     }
1399 
1400     /**
1401      * Verify handling of connection failure.
1402      * The connection failures should trigger connection retries until we hit the max.
1403      */
1404     @Test
testNetworkSpecifierHandleConnectionFailure()1405     public void testNetworkSpecifierHandleConnectionFailure() throws Exception {
1406         sendNetworkRequestAndSetupForConnectionStatus();
1407 
1408         assertNotNull(mSelectedNetwork);
1409 
1410         // Send network connection failure indication beyond the retry limit to trigger the failure
1411         // handling.
1412         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1413             mWifiNetworkFactory.handleConnectionAttemptEnded(
1414                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork);
1415             mLooper.dispatchAll();
1416         }
1417 
1418         mInOrder = inOrder(mAlarmManager, mClientModeImpl);
1419         validateConnectionRetryAttempts();
1420 
1421         verify(mNetworkRequestMatchCallback).onAbort();
1422         // Verify that we sent the connection failure callback.
1423         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1424                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1425         // verify we canceled the timeout alarm.
1426         mInOrder.verify(mAlarmManager).cancel(
1427                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1428         // Verify we reset the network request handling.
1429         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1430         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1431     }
1432 
1433     /**
1434      * Verify handling of connection failure to a different network.
1435      */
1436     @Test
testNetworkSpecifierHandleConnectionFailureToWrongNetwork()1437     public void testNetworkSpecifierHandleConnectionFailureToWrongNetwork() throws Exception {
1438         sendNetworkRequestAndSetupForConnectionStatus();
1439 
1440         // Send network connection failure to a different network indication.
1441         assertNotNull(mSelectedNetwork);
1442         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
1443         connectedNetwork.SSID += "test";
1444         mWifiNetworkFactory.handleConnectionAttemptEnded(
1445                 WifiMetrics.ConnectionEvent.FAILURE_DHCP, connectedNetwork);
1446 
1447         // Verify that we did not send the connection failure callback.
1448         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectFailure(any());
1449         // verify we canceled the timeout alarm.
1450         verify(mAlarmManager, never())
1451                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1452         // Verify we don't reset the network request handling.
1453         verify(mWifiConnectivityManager, never())
1454                 .setSpecificNetworkRequestInProgress(false);
1455 
1456         // Send network connection failure indication beyond the retry limit to trigger the failure
1457         // handling.
1458         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1459             mWifiNetworkFactory.handleConnectionAttemptEnded(
1460                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork);
1461             mLooper.dispatchAll();
1462         }
1463 
1464         mInOrder = inOrder(mAlarmManager, mClientModeImpl);
1465         validateConnectionRetryAttempts();
1466 
1467         // Verify that we sent the connection failure callback.
1468         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1469                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1470         // verify we canceled the timeout alarm.
1471         mInOrder.verify(mAlarmManager).cancel(
1472                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1473         // Verify we reset the network request handling.
1474         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1475         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1476     }
1477 
1478     /**
1479      * Verify handling of connection success.
1480      */
1481     @Test
testNetworkSpecifierHandleConnectionSuccess()1482     public void testNetworkSpecifierHandleConnectionSuccess() throws Exception {
1483         sendNetworkRequestAndSetupForConnectionStatus();
1484 
1485         // Send network connection success indication.
1486         assertNotNull(mSelectedNetwork);
1487         mWifiNetworkFactory.handleConnectionAttemptEnded(
1488                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1489 
1490         // Verify that we sent the connection success callback.
1491         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1492                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1493         // verify we canceled the timeout alarm.
1494         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1495 
1496         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccess();
1497     }
1498 
1499     /**
1500      * Verify that we ignore connection success events after the first one (may be triggered by a
1501      * roam event)
1502      */
1503     @Test
testNetworkSpecifierDuplicateHandleConnectionSuccess()1504     public void testNetworkSpecifierDuplicateHandleConnectionSuccess() throws Exception {
1505         sendNetworkRequestAndSetupForConnectionStatus();
1506 
1507         // Send network connection success indication.
1508         assertNotNull(mSelectedNetwork);
1509         mWifiNetworkFactory.handleConnectionAttemptEnded(
1510                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1511 
1512         // Verify that we sent the connection success callback.
1513         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1514                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1515         // verify we canceled the timeout alarm.
1516         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1517 
1518         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccess();
1519 
1520         // Send second network connection success indication which should be ignored.
1521         mWifiNetworkFactory.handleConnectionAttemptEnded(
1522                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1523         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
1524     }
1525 
1526     /**
1527      * Verify that we ignore any connection failure events after the first connection success (may
1528      * be triggered by a disconnect).
1529      * Note: The disconnect handling will be done via the NetworkAgent.
1530      */
1531     @Test
testNetworkSpecifierHandleConnectionFailureAfterSuccess()1532     public void testNetworkSpecifierHandleConnectionFailureAfterSuccess() throws Exception {
1533         sendNetworkRequestAndSetupForConnectionStatus();
1534 
1535         // Send network connection success indication.
1536         assertNotNull(mSelectedNetwork);
1537         mWifiNetworkFactory.handleConnectionAttemptEnded(
1538                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1539 
1540         // Verify that we sent the connection success callback.
1541         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1542                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1543         // verify we canceled the timeout alarm.
1544         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1545 
1546         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccess();
1547 
1548         // Send a network connection failure indication which should be ignored (beyond the retry
1549         // limit to trigger the failure handling).
1550         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1551             mWifiNetworkFactory.handleConnectionAttemptEnded(
1552                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork);
1553             mLooper.dispatchAll();
1554         }
1555         // Verify that we ignore the second connection failure callback.
1556         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
1557     }
1558 
1559     /**
1560      * Verify handling of connection success to a different network.
1561      */
1562     @Test
testNetworkSpecifierHandleConnectionSuccessToWrongNetwork()1563     public void testNetworkSpecifierHandleConnectionSuccessToWrongNetwork() throws Exception {
1564         sendNetworkRequestAndSetupForConnectionStatus();
1565 
1566         // Send network connection success to a different network indication.
1567         assertNotNull(mSelectedNetwork);
1568         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
1569         connectedNetwork.SSID += "test";
1570         mWifiNetworkFactory.handleConnectionAttemptEnded(
1571                 WifiMetrics.ConnectionEvent.FAILURE_NONE, connectedNetwork);
1572 
1573         // verify that we did not send out the success callback and did not stop the alarm timeout.
1574         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectSuccess(any());
1575         verify(mAlarmManager, never())
1576                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1577 
1578         // Send network connection success to the correct network indication.
1579         mWifiNetworkFactory.handleConnectionAttemptEnded(
1580                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1581 
1582         // Verify that we sent the connection success callback.
1583         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1584                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1585         // verify we canceled the timeout alarm.
1586         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1587     }
1588 
1589     /**
1590      * Verify handling of request release after connecting to the network.
1591      */
1592     @Test
testHandleNetworkReleaseWithSpecifierAfterConnectionSuccess()1593     public void testHandleNetworkReleaseWithSpecifierAfterConnectionSuccess() throws Exception {
1594         sendNetworkRequestAndSetupForConnectionStatus();
1595 
1596         // Send network connection success indication.
1597         assertNotNull(mSelectedNetwork);
1598         mWifiNetworkFactory.handleConnectionAttemptEnded(
1599                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1600 
1601         // Verify that we sent the connection success callback.
1602         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1603                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1604         // verify we canceled the timeout alarm.
1605         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1606 
1607         // Now release the network request.
1608         WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
1609         wcmNetwork.networkId = TEST_NETWORK_ID_1;
1610         wcmNetwork.creatorUid = TEST_UID_1;
1611         wcmNetwork.fromWifiNetworkSpecifier = true;
1612         wcmNetwork.ephemeral = true;
1613         when(mWifiConfigManager.getConfiguredNetwork(mSelectedNetwork.configKey()))
1614                 .thenReturn(wcmNetwork);
1615         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1616         // Verify that we triggered a disconnect.
1617         verify(mClientModeImpl, times(2)).disconnectCommand();
1618         verify(mWifiConfigManager).removeNetwork(TEST_NETWORK_ID_1, TEST_UID_1);
1619         // Re-enable connectivity manager .
1620         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1621     }
1622 
1623     /**
1624      * Verify we return the correct UID when processing network request with network specifier.
1625      */
1626     @Test
testHandleNetworkRequestWithSpecifierGetUid()1627     public void testHandleNetworkRequestWithSpecifierGetUid() throws Exception {
1628         assertEquals(Integer.valueOf(Process.INVALID_UID),
1629                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1630                         new WifiConfiguration()).first);
1631         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1632                         new WifiConfiguration()).second.isEmpty());
1633 
1634         sendNetworkRequestAndSetupForConnectionStatus();
1635         assertNotNull(mSelectedNetwork);
1636 
1637         // connected to a different network.
1638         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
1639         connectedNetwork.SSID += "test";
1640         assertEquals(Integer.valueOf(Process.INVALID_UID),
1641                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1642                         new WifiConfiguration()).first);
1643         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1644                 new WifiConfiguration()).second.isEmpty());
1645 
1646         // connected to the correct network.
1647         connectedNetwork = new WifiConfiguration(mSelectedNetwork);
1648         assertEquals(Integer.valueOf(TEST_UID_1),
1649                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1650                         connectedNetwork).first);
1651         assertEquals(TEST_PACKAGE_NAME_1,
1652                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
1653                         connectedNetwork).second);
1654     }
1655 
1656     /**
1657      *  Verify handling for new network request while processing another one.
1658      */
1659     @Test
testHandleNewNetworkRequestWithSpecifierWhenScanning()1660     public void testHandleNewNetworkRequestWithSpecifierWhenScanning() throws Exception {
1661         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
1662         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
1663         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
1664 
1665         // Register callback.
1666         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
1667                 TEST_CALLBACK_IDENTIFIER);
1668         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(any());
1669 
1670         // Send second request.
1671         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
1672         NetworkRequest newRequest = new NetworkRequest(mNetworkRequest);
1673         newRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1674         mWifiNetworkFactory.needNetworkFor(newRequest, 0);
1675         mLooper.dispatchAll();
1676 
1677         verify(mNetworkRequestMatchCallback).onAbort();
1678         verify(mWifiScanner, times(2)).getSingleScanResults();
1679         verify(mWifiScanner, times(2)).startScan(any(), any(), any());
1680         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1681 
1682         // Remove the stale request1 & ensure nothing happens.
1683         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1684 
1685         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1686                 mAlarmManager, mNetworkRequestMatchCallback);
1687 
1688         // Remove the active request2 & ensure auto-join is re-enabled.
1689         mWifiNetworkFactory.releaseNetworkFor(newRequest);
1690 
1691         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1692     }
1693 
1694     /**
1695      *  Verify handling for new network request while processing another one.
1696      */
1697     @Test
testHandleNewNetworkRequestWithSpecifierAfterMatch()1698     public void testHandleNewNetworkRequestWithSpecifierAfterMatch() throws Exception {
1699         sendNetworkRequestAndSetupForUserSelection();
1700         WifiNetworkSpecifier specifier1 =
1701                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1702 
1703         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1704                 mNetworkRequestUserSelectionCallback.getValue();
1705         assertNotNull(networkRequestUserSelectionCallback);
1706 
1707         // Send second request.
1708         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
1709         NetworkRequest newRequest = new NetworkRequest(mNetworkRequest);
1710         newRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1711         mWifiNetworkFactory.needNetworkFor(newRequest, 0);
1712 
1713         // Ignore stale callbacks.
1714         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1715         networkRequestUserSelectionCallback.select(selectedNetwork);
1716         mLooper.dispatchAll();
1717 
1718         verify(mNetworkRequestMatchCallback).onAbort();
1719         verify(mWifiScanner, times(2)).getSingleScanResults();
1720         verify(mWifiScanner, times(2)).startScan(any(), any(), any());
1721         verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
1722         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1723 
1724         // Remove the stale request1 & ensure nothing happens.
1725         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1726 
1727         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1728                 mAlarmManager, mNetworkRequestMatchCallback);
1729 
1730         // Remove the active request2 & ensure auto-join is re-enabled.
1731         mWifiNetworkFactory.releaseNetworkFor(newRequest);
1732 
1733         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1734     }
1735 
1736     /**
1737      *  Verify handling for new network request while processing another one.
1738      */
1739     @Test
testHandleNewNetworkRequestWithSpecifierAfterConnect()1740     public void testHandleNewNetworkRequestWithSpecifierAfterConnect() throws Exception {
1741         sendNetworkRequestAndSetupForConnectionStatus();
1742         WifiNetworkSpecifier specifier1 =
1743                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1744 
1745         // Send second request.
1746         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
1747         NetworkRequest newRequest = new NetworkRequest(mNetworkRequest);
1748         newRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1749         mWifiNetworkFactory.needNetworkFor(newRequest, 0);
1750 
1751         verify(mNetworkRequestMatchCallback).onAbort();
1752         verify(mWifiConnectivityManager, times(1)).setSpecificNetworkRequestInProgress(true);
1753         verify(mWifiScanner, times(2)).getSingleScanResults();
1754         verify(mWifiScanner, times(2)).startScan(any(), any(), any());
1755         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1756 
1757         // Remove the stale request1 & ensure nothing happens.
1758         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1759 
1760         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1761                 mAlarmManager, mNetworkRequestMatchCallback);
1762 
1763         // Remove the active request2 & ensure auto-join is re-enabled.
1764         mWifiNetworkFactory.releaseNetworkFor(newRequest);
1765 
1766         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1767     }
1768 
1769     /**
1770      *  Verify handling for new network request while processing another one.
1771      */
1772     @Test
testHandleNewNetworkRequestWithSpecifierAfterConnectionSuccess()1773     public void testHandleNewNetworkRequestWithSpecifierAfterConnectionSuccess() throws Exception {
1774         sendNetworkRequestAndSetupForConnectionStatus();
1775         WifiNetworkSpecifier specifier1 =
1776                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1777 
1778         // Send network connection success indication.
1779         assertNotNull(mSelectedNetwork);
1780         mWifiNetworkFactory.handleConnectionAttemptEnded(
1781                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1782         // Cancel the connection timeout.
1783         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1784 
1785         // Send second request.
1786         WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
1787         NetworkRequest newRequest = new NetworkRequest(mNetworkRequest);
1788         newRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1789         mWifiNetworkFactory.needNetworkFor(newRequest, 0);
1790 
1791         verify(mWifiConnectivityManager, times(1)).setSpecificNetworkRequestInProgress(true);
1792         verify(mWifiScanner, times(2)).getSingleScanResults();
1793         verify(mWifiScanner, times(2)).startScan(any(), any(), any());
1794         // we shouldn't disconnect until the user accepts the next request.
1795         verify(mClientModeImpl, times(1)).disconnectCommand();
1796 
1797         // Remove the connected request1 & ensure we disconnect.
1798         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1799         verify(mClientModeImpl, times(2)).disconnectCommand();
1800 
1801         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1802                 mAlarmManager);
1803 
1804         // Now remove the active request2 & ensure auto-join is re-enabled.
1805         mWifiNetworkFactory.releaseNetworkFor(newRequest);
1806 
1807         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1808 
1809         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1810                 mAlarmManager);
1811     }
1812 
1813     /**
1814      *  Verify handling for new network request while processing another one.
1815      */
1816     @Test
testHandleNewNetworkRequestWithSpecifierWhichUserSelectedAfterConnectionSuccess()1817     public void testHandleNewNetworkRequestWithSpecifierWhichUserSelectedAfterConnectionSuccess()
1818             throws Exception {
1819         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
1820         WifiNetworkSpecifier specifier1 =
1821                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1822 
1823         // Send network connection success indication.
1824         assertNotNull(mSelectedNetwork);
1825         mWifiNetworkFactory.handleConnectionAttemptEnded(
1826                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1827         // Cancel the connection timeout.
1828         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1829 
1830         // Send second request & we simulate the user selecting the request & connecting to it.
1831         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager);
1832         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_2);
1833         WifiNetworkSpecifier specifier2 =
1834                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1835         assertNotNull(mSelectedNetwork);
1836         mWifiNetworkFactory.handleConnectionAttemptEnded(
1837                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1838         // Cancel the connection timeout.
1839         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1840 
1841         // We shouldn't explicitly disconnect, the new connection attempt will implicitly disconnect
1842         // from the connected network.
1843         verify(mClientModeImpl, times(2)).disconnectCommand();
1844 
1845         // Remove the stale request1 & ensure nothing happens (because it was replaced by the
1846         // second request)
1847         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
1848         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1849 
1850         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1851                 mAlarmManager);
1852 
1853         // Now remove the rejected request2, ensure we disconnect & re-enable auto-join.
1854         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1855         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1856         verify(mClientModeImpl, times(3)).disconnectCommand();
1857         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1858 
1859         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1860                 mAlarmManager);
1861     }
1862 
1863     /**
1864      *  Verify handling for new network request while processing another one.
1865      */
1866     @Test
testHandleNewNetworkRequestWithSpecifierWhichUserRejectedAfterConnectionSuccess()1867     public void testHandleNewNetworkRequestWithSpecifierWhichUserRejectedAfterConnectionSuccess()
1868             throws Exception {
1869         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
1870         WifiNetworkSpecifier specifier1 =
1871                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1872 
1873         // Send network connection success indication.
1874         assertNotNull(mSelectedNetwork);
1875         mWifiNetworkFactory.handleConnectionAttemptEnded(
1876                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
1877         // Cancel the connection timeout.
1878         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1879 
1880         // Send second request & we simulate the user rejecting the request.
1881         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager);
1882         sendNetworkRequestAndSetupForUserSelection(TEST_SSID_2);
1883         WifiNetworkSpecifier specifier2 =
1884                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
1885         mNetworkRequestUserSelectionCallback.getValue().reject();
1886         mLooper.dispatchAll();
1887         // cancel periodic scans.
1888         verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
1889 
1890         // we shouldn't disconnect/re-enable auto-join until the connected request is released.
1891         verify(mWifiConnectivityManager, never()).setSpecificNetworkRequestInProgress(false);
1892         verify(mClientModeImpl, times(1)).disconnectCommand();
1893 
1894         // Remove the connected request1 & ensure we disconnect & ensure auto-join is re-enabled.
1895         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
1896         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1897         verify(mClientModeImpl, times(2)).disconnectCommand();
1898         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1899 
1900         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1901                 mAlarmManager);
1902 
1903         // Now remove the rejected request2 & ensure nothing happens
1904         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
1905         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1906 
1907         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
1908                 mAlarmManager);
1909     }
1910 
1911     /**
1912      * Verify handling of screen state changes while triggering periodic scans to find matching
1913      * networks.
1914      */
1915     @Test
testNetworkSpecifierHandleScreenStateChangedWhileScanning()1916     public void testNetworkSpecifierHandleScreenStateChangedWhileScanning() throws Exception {
1917         sendNetworkRequestAndSetupForUserSelection();
1918 
1919         // Turn off screen.
1920         mWifiNetworkFactory.handleScreenStateChanged(false);
1921 
1922         // 1. Cancel the scan timer.
1923         mInOrder.verify(mAlarmManager).cancel(
1924                 mPeriodicScanListenerArgumentCaptor.getValue());
1925         // 2. Simulate the scan results from an ongoing scan, ensure no more scans are scheduled.
1926         mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas);
1927 
1928         // Ensure no more interactions.
1929         mInOrder.verifyNoMoreInteractions();
1930 
1931         // Now, turn the screen on.
1932         mWifiNetworkFactory.handleScreenStateChanged(true);
1933 
1934         // Verify that we resumed periodic scanning.
1935         mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
1936     }
1937 
1938     /**
1939      * Verify handling of screen state changes after the active network request was released.
1940      */
1941     @Test
testNetworkSpecifierHandleScreenStateChangedWithoutActiveRequest()1942     public void testNetworkSpecifierHandleScreenStateChangedWithoutActiveRequest()
1943             throws Exception {
1944         sendNetworkRequestAndSetupForUserSelection();
1945         // Now release the active network request.
1946         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1947         // Cancel the scan timer on release.
1948         mInOrder.verify(mAlarmManager).cancel(
1949                 mPeriodicScanListenerArgumentCaptor.getValue());
1950 
1951         // Turn off screen.
1952         mWifiNetworkFactory.handleScreenStateChanged(false);
1953 
1954         // Now, turn the screen on.
1955         mWifiNetworkFactory.handleScreenStateChanged(true);
1956 
1957         // Ensure that we did not pause or resume scanning.
1958         mInOrder.verifyNoMoreInteractions();
1959     }
1960 
1961     /**
1962      * Verify handling of screen state changes after user selected a network to connect to.
1963      */
1964     @Test
testNetworkSpecifierHandleScreenStateChangedAfterUserSelection()1965     public void testNetworkSpecifierHandleScreenStateChangedAfterUserSelection() throws Exception {
1966         sendNetworkRequestAndSetupForConnectionStatus();
1967 
1968         // Turn off screen.
1969         mWifiNetworkFactory.handleScreenStateChanged(false);
1970 
1971         // Now, turn the screen on.
1972         mWifiNetworkFactory.handleScreenStateChanged(true);
1973 
1974         // Ensure that we did not pause or resume scanning.
1975         mInOrder.verifyNoMoreInteractions();
1976     }
1977 
1978     /**
1979      * Verify we don't accept specific network request when wifi is off.
1980      */
1981     @Test
testHandleAcceptNetworkRequestWithSpecifierWhenWifiOff()1982     public void testHandleAcceptNetworkRequestWithSpecifierWhenWifiOff() throws Exception {
1983         when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
1984                 .thenReturn(IMPORTANCE_FOREGROUND);
1985 
1986         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
1987         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
1988 
1989         // set wifi off.
1990         mWifiNetworkFactory.setWifiState(false);
1991         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
1992 
1993         // set wifi on.
1994         mWifiNetworkFactory.setWifiState(true);
1995         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0));
1996     }
1997 
1998     /**
1999      * Verify handling of new network request with network specifier when wifi is off.
2000      */
2001     @Test
testHandleNetworkRequestWithSpecifierWhenWifiOff()2002     public void testHandleNetworkRequestWithSpecifierWhenWifiOff() {
2003         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
2004         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2005 
2006         // set wifi off
2007         mWifiNetworkFactory.setWifiState(false);
2008         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2009         verify(mWifiScanner, never()).startScan(any(), any(), any());
2010 
2011         // set wifi on
2012         mWifiNetworkFactory.setWifiState(true);
2013         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2014         verify(mWifiScanner).startScan(any(), any(), any());
2015     }
2016 
2017     /**
2018      *  Verify wifi toggle off when scanning.
2019      */
2020     @Test
testHandleNetworkRequestWithSpecifierWifiOffWhenScanning()2021     public void testHandleNetworkRequestWithSpecifierWifiOffWhenScanning() throws Exception {
2022         WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
2023         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
2024         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2025 
2026         // Register callback.
2027         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2028                 TEST_CALLBACK_IDENTIFIER);
2029         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(any());
2030 
2031         verify(mWifiScanner).startScan(any(), any(), any());
2032 
2033         // toggle wifi off & verify we aborted ongoing request.
2034         mWifiNetworkFactory.setWifiState(false);
2035         verify(mNetworkRequestMatchCallback).onAbort();
2036         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2037     }
2038 
2039     /**
2040      *  Verify wifi toggle off after connection attempt is started.
2041      */
2042     @Test
testHandleNetworkRequestWithSpecifierWifiOffAfterConnect()2043     public void testHandleNetworkRequestWithSpecifierWifiOffAfterConnect() throws Exception {
2044         sendNetworkRequestAndSetupForConnectionStatus();
2045 
2046         // toggle wifi off & verify we aborted ongoing request.
2047         mWifiNetworkFactory.setWifiState(false);
2048         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2049         verify(mNetworkRequestMatchCallback).onAbort();
2050         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2051     }
2052 
2053     /**
2054      * Verify handling of new network request with network specifier when wifi is off & then on.
2055      * Note: Unlike the other unit tests, this test invokes the top level
2056      * {@link NetworkFactory#CMD_REQUEST_NETWORK} to simulate the full flow.
2057      */
2058     @Test
testFullHandleNetworkRequestWithSpecifierWhenWifiOff()2059     public void testFullHandleNetworkRequestWithSpecifierWhenWifiOff() {
2060         WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false);
2061         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2062 
2063         // set wifi off
2064         mWifiNetworkFactory.setWifiState(false);
2065         // Add the request, should do nothing.
2066         Message message = Message.obtain();
2067         message.what = CMD_REQUEST_NETWORK;
2068         message.obj = mNetworkRequest;
2069         mWifiNetworkFactory.sendMessage(message);
2070         mLooper.dispatchAll();
2071         verify(mWifiScanner, never()).startScan(any(), any(), any());
2072 
2073         // set wifi on
2074         mWifiNetworkFactory.setWifiState(true);
2075         mLooper.dispatchAll();
2076         // Should trigger a re-evaluation of existing requests and the pending request will be
2077         // processed now.
2078         verify(mWifiScanner).startScan(any(), any(), any());
2079     }
2080 
2081     /**
2082      * Verify the user approval bypass for a specific request for an access point that was already
2083      * approved previously with no cached scan results matching.
2084      */
2085     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithNoCache()2086     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithNoCache()
2087             throws Exception {
2088         // 1. First request (no user approval bypass)
2089         sendNetworkRequestAndSetupForConnectionStatus();
2090 
2091         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2092         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2093 
2094         // 2. Second request for the same access point (user approval bypass).
2095         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2096         PatternMatcher ssidPatternMatch =
2097                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2098         Pair<MacAddress, MacAddress> bssidPatternMatch =
2099                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2100                         MacAddress.BROADCAST_ADDRESS);
2101         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2102                 ssidPatternMatch, bssidPatternMatch,
2103                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
2104         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2105         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2106 
2107         validateUiStartParams(true);
2108 
2109         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2110                 TEST_CALLBACK_IDENTIFIER);
2111         // Trigger scan results & ensure we triggered a connect.
2112         verify(mWifiScanner).startScan(any(), mScanListenerArgumentCaptor.capture(), any());
2113         ScanListener scanListener = mScanListenerArgumentCaptor.getValue();
2114         assertNotNull(scanListener);
2115         scanListener.onResults(mTestScanDatas);
2116 
2117         // Verify we did not trigger the match callback.
2118         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
2119         // Verify that we sent a connection attempt to ClientModeImpl
2120         verify(mClientModeImpl).sendMessage(any());
2121 
2122         verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
2123     }
2124 
2125     /**
2126      * Verify that we don't bypass user approval for a specific request for an access point that was
2127      * approved previously, but then the user forgot it sometime after.
2128      */
2129     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNForgot()2130     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNForgot()
2131             throws Exception {
2132         // 1. First request (no user approval bypass)
2133         sendNetworkRequestAndSetupForConnectionStatus();
2134 
2135         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2136         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2137 
2138         // 2. Simulate user forgeting the network.
2139         when(mWifiConfigManager.wasEphemeralNetworkDeleted(
2140                 ScanResultUtil.createQuotedSSID(mTestScanDatas[0].getResults()[0].SSID)))
2141                 .thenReturn(true);
2142 
2143         // 3. Second request for the same access point (user approval bypass).
2144         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2145         PatternMatcher ssidPatternMatch =
2146                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2147         Pair<MacAddress, MacAddress> bssidPatternMatch =
2148                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2149                         MacAddress.BROADCAST_ADDRESS);
2150         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2151                 ssidPatternMatch, bssidPatternMatch,
2152                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
2153         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2154         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2155         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2156                 TEST_CALLBACK_IDENTIFIER);
2157         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2158         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2159                 ArgumentCaptor.forClass(List.class);
2160         // Verify we triggered the match callback.
2161         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2162         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2163         assertNotNull(matchedScanResultsCaptor.getValue());
2164         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2165         // Verify that we did not send a connection attempt to ClientModeImpl.
2166         verify(mClientModeImpl, never()).sendMessage(any());
2167     }
2168 
2169     /**
2170      * Verify that we don't bypass user approval for a specific request for an access point that was
2171      * not approved previously.
2172      */
2173     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchNotApproved()2174     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchNotApproved()
2175             throws Exception {
2176         // 1. First request (no user approval bypass)
2177         sendNetworkRequestAndSetupForConnectionStatus();
2178 
2179         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2180         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2181 
2182         // 2. Second request for a different access point (but same network).
2183         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
2184                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_3, TEST_SSID_4);
2185         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[1];
2186         PatternMatcher ssidPatternMatch =
2187                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2188         Pair<MacAddress, MacAddress> bssidPatternMatch =
2189                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2190                         MacAddress.BROADCAST_ADDRESS);
2191         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2192                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2193                 TEST_UID_1, TEST_PACKAGE_NAME_1);
2194         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2195         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2196         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2197                 TEST_CALLBACK_IDENTIFIER);
2198         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2199         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2200                 ArgumentCaptor.forClass(List.class);
2201         // Verify we triggered the match callback.
2202         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2203         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2204         assertNotNull(matchedScanResultsCaptor.getValue());
2205         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2206         // Verify that we did not send a connection attempt to ClientModeImpl.
2207         verify(mClientModeImpl, never()).sendMessage(any());
2208     }
2209 
2210     /**
2211      * Verify that we don't bypass user approval for a specific request for a network
2212      * (not access point) that was approved previously.
2213      */
2214     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved()2215     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved()
2216             throws Exception {
2217         // 1. First request (no user approval bypass)
2218         sendNetworkRequestAndSetupForConnectionStatus();
2219 
2220         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2221         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2222 
2223         // 2. Second request for the same network (but not specific access point)
2224         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2225         PatternMatcher ssidPatternMatch =
2226                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2227         // match-all.
2228         Pair<MacAddress, MacAddress> bssidPatternMatch =
2229                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
2230         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2231                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2232                 TEST_UID_1, TEST_PACKAGE_NAME_1);
2233         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2234         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2235         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2236                 TEST_CALLBACK_IDENTIFIER);
2237         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2238         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2239                 ArgumentCaptor.forClass(List.class);
2240         // Verify we triggered the match callback.
2241         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2242         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2243         assertNotNull(matchedScanResultsCaptor.getValue());
2244         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2245         // Verify that we did not send a connection attempt to ClientModeImpl.
2246         verify(mClientModeImpl, never()).sendMessage(any());
2247     }
2248 
2249     /**
2250      * Verify the we don't bypass user approval for a specific request for an access point that was
2251      * already approved previously, but was then removed (app uninstalled, user deleted it from
2252      * notification, from tests, etc).
2253      */
2254     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterApprovalsRemove()2255     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterApprovalsRemove()
2256             throws Exception {
2257         // 1. First request (no user approval bypass)
2258         sendNetworkRequestAndSetupForConnectionStatus();
2259 
2260         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2261         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2262 
2263         // 2. Remove all approvals for the app.
2264         mWifiNetworkFactory.removeUserApprovedAccessPointsForApp(TEST_PACKAGE_NAME_1);
2265 
2266         // 3. Second request for the same access point
2267         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2268         PatternMatcher ssidPatternMatch =
2269                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2270         Pair<MacAddress, MacAddress> bssidPatternMatch =
2271                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2272                         MacAddress.ALL_ZEROS_ADDRESS);
2273         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2274                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2275                 TEST_UID_1, TEST_PACKAGE_NAME_1);
2276         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2277         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2278         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2279                 TEST_CALLBACK_IDENTIFIER);
2280         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2281         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2282                 ArgumentCaptor.forClass(List.class);
2283         // Verify we triggered the match callback.
2284         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2285         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2286         assertNotNull(matchedScanResultsCaptor.getValue());
2287         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2288         // Verify that we did not send a connection attempt to ClientModeImpl.
2289         verify(mClientModeImpl, never()).sendMessage(any());
2290     }
2291 
2292     /**
2293      * Verify the we don't bypass user approval for a specific request for an access point that was
2294      * already approved previously, but then the user perform network settings reset.
2295      */
2296     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterClear()2297     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterClear()
2298             throws Exception {
2299         // 1. First request (no user approval bypass)
2300         sendNetworkRequestAndSetupForConnectionStatus();
2301 
2302         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2303         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2304 
2305         // 2. Remove all approvals.
2306         mWifiNetworkFactory.clear();
2307 
2308         // 3. Second request for the same access point
2309         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2310         PatternMatcher ssidPatternMatch =
2311                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2312         Pair<MacAddress, MacAddress> bssidPatternMatch =
2313                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2314                         MacAddress.ALL_ZEROS_ADDRESS);
2315         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2316                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2317                 TEST_UID_1, TEST_PACKAGE_NAME_1);
2318         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2319         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2320         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2321                 TEST_CALLBACK_IDENTIFIER);
2322         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2323         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2324                 ArgumentCaptor.forClass(List.class);
2325         // Verify we triggered the match callback.
2326         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2327         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2328         assertNotNull(matchedScanResultsCaptor.getValue());
2329         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2330         // Verify that we did not send a connection attempt to ClientModeImpl.
2331         verify(mClientModeImpl, never()).sendMessage(any());
2332     }
2333 
2334     /**
2335      * Verify the config store save for store user approval.
2336      */
2337     @Test
testNetworkSpecifierUserApprovalConfigStoreSave()2338     public void testNetworkSpecifierUserApprovalConfigStoreSave()
2339             throws Exception {
2340         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
2341 
2342         // Verify config store interactions.
2343         verify(mWifiConfigManager).saveToStore(true);
2344         assertTrue(mDataSource.hasNewDataToSerialize());
2345 
2346         Map<String, Set<AccessPoint>> approvedAccessPointsMapToWrite = mDataSource.toSerialize();
2347         assertEquals(1, approvedAccessPointsMapToWrite.size());
2348         assertTrue(approvedAccessPointsMapToWrite.keySet().contains(TEST_PACKAGE_NAME_1));
2349         Set<AccessPoint> approvedAccessPointsToWrite =
2350                 approvedAccessPointsMapToWrite.get(TEST_PACKAGE_NAME_1);
2351         Set<AccessPoint> expectedApprovedAccessPoints =
2352                 new HashSet<AccessPoint>() {{
2353                     add(new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
2354                             WifiConfiguration.SECURITY_TYPE_PSK));
2355                 }};
2356         assertEquals(expectedApprovedAccessPoints, approvedAccessPointsToWrite);
2357         // Ensure that the new data flag has been reset after read.
2358         assertFalse(mDataSource.hasNewDataToSerialize());
2359     }
2360 
2361     /**
2362      * Verify the config store load for store user approval.
2363      */
2364     @Test
testNetworkSpecifierUserApprovalConfigStoreLoad()2365     public void testNetworkSpecifierUserApprovalConfigStoreLoad()
2366             throws Exception {
2367         Map<String, Set<AccessPoint>> approvedAccessPointsMapToRead = new HashMap<>();
2368         Set<AccessPoint> approvedAccessPoints =
2369                 new HashSet<AccessPoint>() {{
2370                     add(new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
2371                             WifiConfiguration.SECURITY_TYPE_PSK));
2372                 }};
2373         approvedAccessPointsMapToRead.put(TEST_PACKAGE_NAME_1, approvedAccessPoints);
2374         mDataSource.fromDeserialized(approvedAccessPointsMapToRead);
2375 
2376         // The new network request should bypass user approval for the same access point.
2377         PatternMatcher ssidPatternMatch =
2378                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2379         Pair<MacAddress, MacAddress> bssidPatternMatch =
2380                 Pair.create(MacAddress.fromString(TEST_BSSID_1),
2381                         MacAddress.BROADCAST_ADDRESS);
2382         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2383                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2384                 TEST_UID_1, TEST_PACKAGE_NAME_1);
2385         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2386         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2387         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2388                 TEST_CALLBACK_IDENTIFIER);
2389         // Trigger scan results & ensure we triggered a connect.
2390         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
2391                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
2392         verify(mWifiScanner).startScan(any(), mScanListenerArgumentCaptor.capture(), any());
2393         ScanListener scanListener = mScanListenerArgumentCaptor.getValue();
2394         assertNotNull(scanListener);
2395         scanListener.onResults(mTestScanDatas);
2396 
2397         // Verify we did not trigger the match callback.
2398         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
2399         // Verify that we sent a connection attempt to ClientModeImpl
2400         verify(mClientModeImpl).sendMessage(any());
2401     }
2402 
2403     /**
2404      * Verify the config store save and load could preserve the elements order.
2405      */
2406     @Test
testStoreConfigSaveAndLoadPreserveOrder()2407     public void testStoreConfigSaveAndLoadPreserveOrder() throws Exception {
2408         LinkedHashSet<AccessPoint> approvedApSet = new LinkedHashSet<>();
2409         approvedApSet.add(new AccessPoint(TEST_SSID_1,
2410                 MacAddress.fromString(TEST_BSSID_1), WifiConfiguration.SECURITY_TYPE_PSK));
2411         approvedApSet.add(new AccessPoint(TEST_SSID_2,
2412                 MacAddress.fromString(TEST_BSSID_2), WifiConfiguration.SECURITY_TYPE_PSK));
2413         approvedApSet.add(new AccessPoint(TEST_SSID_3,
2414                 MacAddress.fromString(TEST_BSSID_3), WifiConfiguration.SECURITY_TYPE_PSK));
2415         approvedApSet.add(new AccessPoint(TEST_SSID_4,
2416                 MacAddress.fromString(TEST_BSSID_4), WifiConfiguration.SECURITY_TYPE_PSK));
2417         mWifiNetworkFactory.mUserApprovedAccessPointMap.put(TEST_PACKAGE_NAME_1,
2418                 new LinkedHashSet<>(approvedApSet));
2419         // Save config.
2420         byte[] xmlData = serializeData();
2421         mWifiNetworkFactory.mUserApprovedAccessPointMap.clear();
2422         // Load config.
2423         deserializeData(xmlData);
2424 
2425         LinkedHashSet<AccessPoint> storedApSet = mWifiNetworkFactory
2426                 .mUserApprovedAccessPointMap.get(TEST_PACKAGE_NAME_1);
2427         // Check load config success and order preserved.
2428         assertNotNull(storedApSet);
2429         assertArrayEquals(approvedApSet.toArray(), storedApSet.toArray());
2430     }
2431 
2432     /**
2433      * Verify the user approval bypass for a specific request for an access point that was already
2434      * approved previously and the scan result is present in the cached scan results.
2435      */
2436     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithCache()2437     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithCache()
2438             throws Exception {
2439         // 1. First request (no user approval bypass)
2440         sendNetworkRequestAndSetupForConnectionStatus();
2441 
2442         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2443         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2444 
2445         // 2. Second request for the same access point (user approval bypass).
2446         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2447         // simulate no cache expiry
2448         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2449         // Simulate the cached results matching.
2450         when(mWifiScanner.getSingleScanResults())
2451                 .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
2452 
2453         PatternMatcher ssidPatternMatch =
2454                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2455         Pair<MacAddress, MacAddress> bssidPatternMatch =
2456                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2457                         MacAddress.BROADCAST_ADDRESS);
2458         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2459                 ssidPatternMatch, bssidPatternMatch,
2460                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
2461         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2462         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2463 
2464         // Verify we did not trigger the UI for the second request.
2465         verify(mContext, times(1)).startActivityAsUser(any(), any());
2466         // Verify we did not trigger a scan.
2467         verify(mWifiScanner, never()).startScan(any(), any(), any());
2468         // Verify we did not trigger the match callback.
2469         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
2470         // Verify that we sent a connection attempt to ClientModeImpl
2471         verify(mClientModeImpl).sendMessage(any());
2472 
2473         verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
2474     }
2475 
2476     /**
2477      * Verify the user approval bypass for a specific request for an access point that was already
2478      * approved previously and the scan result is present in the cached scan results, but the
2479      * results are stale.
2480      */
2481     @Test
2482     public void
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithStaleCache()2483             testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedWithStaleCache()
2484             throws Exception {
2485         // 1. First request (no user approval bypass)
2486         sendNetworkRequestAndSetupForConnectionStatus();
2487 
2488         mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER);
2489         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeImpl);
2490 
2491         long scanResultsTimestampInUs = 39484839202L;
2492         mTestScanDatas[0].getResults()[0].timestamp = scanResultsTimestampInUs;
2493         mTestScanDatas[0].getResults()[1].timestamp = scanResultsTimestampInUs;
2494         mTestScanDatas[0].getResults()[2].timestamp = scanResultsTimestampInUs;
2495         mTestScanDatas[0].getResults()[3].timestamp = scanResultsTimestampInUs;
2496 
2497         // 2. Second request for the same access point (user approval bypass).
2498         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2499         // simulate cache expiry
2500         when(mClock.getElapsedSinceBootMillis())
2501                 .thenReturn(Long.valueOf(
2502                         scanResultsTimestampInUs / 1000
2503                         + WifiNetworkFactory.CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS + 1));
2504         // Simulate the cached results matching.
2505         when(mWifiScanner.getSingleScanResults())
2506                 .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
2507 
2508         PatternMatcher ssidPatternMatch =
2509                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2510         Pair<MacAddress, MacAddress> bssidPatternMatch =
2511                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2512                         MacAddress.BROADCAST_ADDRESS);
2513         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2514                 ssidPatternMatch, bssidPatternMatch,
2515                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
2516         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2517         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2518 
2519         // Ensure we brought up the UI while the scan is ongoing.
2520         validateUiStartParams(true);
2521 
2522         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2523                 TEST_CALLBACK_IDENTIFIER);
2524         // Trigger scan results & ensure we triggered a connect.
2525         verify(mWifiScanner).startScan(any(), mScanListenerArgumentCaptor.capture(), any());
2526         ScanListener scanListener = mScanListenerArgumentCaptor.getValue();
2527         assertNotNull(scanListener);
2528         scanListener.onResults(mTestScanDatas);
2529 
2530         // Verify we did not trigger the match callback.
2531         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
2532         // Verify that we sent a connection attempt to ClientModeImpl
2533         verify(mClientModeImpl).sendMessage(any());
2534 
2535         verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
2536     }
2537 
2538     /**
2539      * Verify network specifier matching for a specifier containing a specific SSID match using
2540      * 4 WPA_PSK scan results, each with unique SSID when the UI callback registration is delayed.
2541      */
2542     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchCallbackRegistrationDelayed()2543     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchCallbackRegistrationDelayed()
2544             throws Exception {
2545         // Setup scan data for open networks.
2546         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
2547                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
2548 
2549         // Setup network specifier for open networks.
2550         PatternMatcher ssidPatternMatch =
2551                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2552         Pair<MacAddress, MacAddress> bssidPatternMatch =
2553                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
2554         WifiConfiguration wifiConfiguration = new WifiConfiguration();
2555         wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2556         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2557                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
2558                 TEST_PACKAGE_NAME_1);
2559 
2560         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2561         mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
2562 
2563         validateUiStartParams(true);
2564 
2565         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2566 
2567         // Ensure we did not send any match callbacks, until the callback is registered
2568         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
2569 
2570         // Register the callback & ensure we triggered the on match callback.
2571         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2572                 TEST_CALLBACK_IDENTIFIER);
2573         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2574                 ArgumentCaptor.forClass(List.class);
2575         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2576 
2577         assertNotNull(matchedScanResultsCaptor.getValue());
2578         // We only expect 1 network match in this case.
2579         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
2580 
2581         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
2582                 matchedScanResultsCaptor.getValue().size());
2583     }
2584 
sendNetworkRequestAndSetupForConnectionStatus()2585     private Messenger sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
2586         return sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
2587     }
2588 
2589     // Helper method to setup the necessary pre-requisite steps for tracking connection status.
sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)2590     private Messenger sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)
2591             throws RemoteException {
2592         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2593 
2594         sendNetworkRequestAndSetupForUserSelection(targetSsid);
2595 
2596         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
2597                 mNetworkRequestUserSelectionCallback.getValue();
2598         assertNotNull(networkRequestUserSelectionCallback);
2599 
2600         // Now trigger user selection to one of the network.
2601         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
2602         mSelectedNetwork.SSID = "\"" + targetSsid + "\"";
2603         networkRequestUserSelectionCallback.select(mSelectedNetwork);
2604         mLooper.dispatchAll();
2605 
2606         // Cancel the periodic scan timer.
2607         mInOrder.verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
2608         // Disable connectivity manager
2609         verify(mWifiConnectivityManager, atLeastOnce()).setSpecificNetworkRequestInProgress(true);
2610         // Increment the number of unique apps.
2611         verify(mWifiMetrics).incrementNetworkRequestApiNumApps();
2612 
2613         verify(mClientModeImpl, atLeastOnce()).disconnectCommand();
2614         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
2615         verify(mClientModeImpl, atLeastOnce()).sendMessage(messageCaptor.capture());
2616 
2617         Message message = messageCaptor.getValue();
2618         assertNotNull(message);
2619 
2620         // Start the connection timeout alarm.
2621         mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
2622                 eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
2623                 mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
2624         assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2625 
2626         return message.replyTo;
2627     }
2628 
sendNetworkRequestAndSetupForUserSelection()2629     private void sendNetworkRequestAndSetupForUserSelection() throws RemoteException {
2630         sendNetworkRequestAndSetupForUserSelection(TEST_SSID_1);
2631     }
2632 
2633     // Helper method to setup the necessary pre-requisite steps for user selection.
sendNetworkRequestAndSetupForUserSelection(String targetSsid)2634     private void sendNetworkRequestAndSetupForUserSelection(String targetSsid)
2635             throws RemoteException {
2636         // Setup scan data for WPA-PSK networks.
2637         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
2638                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
2639 
2640         // Setup network specifier for WPA-PSK networks.
2641         PatternMatcher ssidPatternMatch =
2642                 new PatternMatcher(targetSsid, PatternMatcher.PATTERN_LITERAL);
2643         Pair<MacAddress, MacAddress> bssidPatternMatch =
2644                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
2645         WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork();
2646         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
2647         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
2648                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
2649                 TEST_PACKAGE_NAME_1);
2650 
2651         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
2652         mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest), 0);
2653 
2654         validateUiStartParams(true);
2655 
2656         mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
2657                 TEST_CALLBACK_IDENTIFIER);
2658         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
2659                 mNetworkRequestUserSelectionCallback.capture());
2660 
2661         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2662 
2663         verify(mNetworkRequestMatchCallback, atLeastOnce()).onMatch(anyList());
2664     }
2665 
2666     // Simulates the periodic scans performed to find a matching network.
2667     // a) Start scan
2668     // b) Scan results received.
2669     // c) Set alarm for next scan at the expected interval.
2670     // d) Alarm fires, go to step a) again and repeat.
verifyPeriodicScans(long...expectedIntervalsInSeconds)2671     private void verifyPeriodicScans(long...expectedIntervalsInSeconds) {
2672         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2673 
2674         OnAlarmListener alarmListener = null;
2675         ScanListener scanListener = null;
2676 
2677         mInOrder = inOrder(mWifiScanner, mAlarmManager);
2678 
2679         // Before we start scans, ensure that we look at the latest cached scan results.
2680         mInOrder.verify(mWifiScanner).getSingleScanResults();
2681 
2682         for (int i = 0; i < expectedIntervalsInSeconds.length - 1; i++) {
2683             long expectedCurrentIntervalInMs = expectedIntervalsInSeconds[i];
2684             long expectedNextIntervalInMs = expectedIntervalsInSeconds[i + 1];
2685 
2686             // First scan is immediately fired, so need for the alarm to fire.
2687             if (expectedCurrentIntervalInMs != 0) {
2688                 // Fire the alarm and ensure that we started the next scan.
2689                 alarmListener.onAlarm();
2690             }
2691             mInOrder.verify(mWifiScanner).startScan(
2692                     any(), mScanListenerArgumentCaptor.capture(), any());
2693             scanListener = mScanListenerArgumentCaptor.getValue();
2694             assertNotNull(scanListener);
2695 
2696             // Now trigger the scan results callback and verify the alarm set for the next scan.
2697             scanListener.onResults(mTestScanDatas);
2698 
2699             mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
2700                     eq(expectedNextIntervalInMs), any(),
2701                     mPeriodicScanListenerArgumentCaptor.capture(), any());
2702             alarmListener = mPeriodicScanListenerArgumentCaptor.getValue();
2703             assertNotNull(alarmListener);
2704         }
2705 
2706         mInOrder.verifyNoMoreInteractions();
2707     }
2708 
createWifiNetworkSpecifier(int uid, boolean isHidden)2709     private WifiNetworkSpecifier createWifiNetworkSpecifier(int uid, boolean isHidden) {
2710         PatternMatcher ssidPatternMatch =
2711                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2712         Pair<MacAddress, MacAddress> bssidPatternMatch =
2713                 Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
2714         WifiConfiguration wifiConfiguration;
2715         if (isHidden) {
2716             wifiConfiguration = WifiConfigurationTestUtil.createPskHiddenNetwork();
2717         } else {
2718             wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork();
2719         }
2720         String packageName = null;
2721         if (uid == TEST_UID_1) {
2722             packageName = TEST_PACKAGE_NAME_1;
2723         } else if (uid == TEST_UID_2) {
2724             packageName = TEST_PACKAGE_NAME_2;
2725         } else {
2726             fail();
2727         }
2728         return new WifiNetworkSpecifier(
2729                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, uid, packageName);
2730     }
2731 
2732     private static final int SCAN_RESULT_TYPE_OPEN = 0;
2733     private static final int SCAN_RESULT_TYPE_WPA_PSK = 1;
2734     private static final int SCAN_RESULT_TYPE_WPA_EAP = 2;
2735 
getScanResultCapsForType(int scanResultType)2736     private String getScanResultCapsForType(int scanResultType) {
2737         switch (scanResultType) {
2738             case SCAN_RESULT_TYPE_OPEN:
2739                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
2740                         WifiConfigurationTestUtil.createOpenNetwork());
2741             case SCAN_RESULT_TYPE_WPA_PSK:
2742                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
2743                         WifiConfigurationTestUtil.createPskNetwork());
2744             case SCAN_RESULT_TYPE_WPA_EAP:
2745                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
2746                         WifiConfigurationTestUtil.createEapNetwork());
2747         }
2748         fail("Invalid scan result type " + scanResultType);
2749         return "";
2750     }
2751 
2752     // Helper method to setup the scan data for verifying the matching algo.
setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3, String ssid4)2753     private void setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3,
2754             String ssid4) {
2755         // 4 scan results,
2756         assertEquals(1, mTestScanDatas.length);
2757         ScanResult[] scanResults = mTestScanDatas[0].getResults();
2758         assertEquals(4, scanResults.length);
2759 
2760         String caps = getScanResultCapsForType(scanResultType);
2761 
2762         // Scan results have increasing RSSI.
2763         scanResults[0].SSID = ssid1;
2764         scanResults[0].BSSID = TEST_BSSID_1;
2765         scanResults[0].capabilities = caps;
2766         scanResults[0].level = -45;
2767         scanResults[1].SSID = ssid2;
2768         scanResults[1].BSSID = TEST_BSSID_2;
2769         scanResults[1].capabilities = caps;
2770         scanResults[1].level = -35;
2771         scanResults[2].SSID = ssid3;
2772         scanResults[2].BSSID = TEST_BSSID_3;
2773         scanResults[2].capabilities = caps;
2774         scanResults[2].level = -25;
2775         scanResults[3].SSID = ssid4;
2776         scanResults[3].BSSID = TEST_BSSID_4;
2777         scanResults[3].capabilities = caps;
2778         scanResults[3].level = -15;
2779     }
2780 
validateScanResults( List<ScanResult> actualScanResults, ScanResult...expectedScanResults)2781     private void validateScanResults(
2782             List<ScanResult> actualScanResults, ScanResult...expectedScanResults) {
2783         assertEquals(expectedScanResults.length, actualScanResults.size());
2784         for (int i = 0; i < expectedScanResults.length; i++) {
2785             ScanResult expectedScanResult = expectedScanResults[i];
2786             ScanResult actualScanResult = actualScanResults.stream()
2787                     .filter(x -> x.BSSID.equals(expectedScanResult.BSSID))
2788                     .findFirst()
2789                     .orElse(null);
2790             ScanTestUtil.assertScanResultEquals(expectedScanResult, actualScanResult);
2791         }
2792     }
2793 
validateConnectionRetryAttempts()2794     private void validateConnectionRetryAttempts() {
2795         for (int i = 0; i < WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
2796             // Cancel the existing connection timeout.
2797             mInOrder.verify(mAlarmManager).cancel(
2798                     mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2799 
2800             // Trigger new connection.
2801             ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
2802             mInOrder.verify(mClientModeImpl).sendMessage(messageCaptor.capture());
2803             Message message = messageCaptor.getValue();
2804             assertNotNull(message);
2805             assertEquals(WifiManager.CONNECT_NETWORK, message.what);
2806 
2807             // Start the new connection timeout alarm.
2808             mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
2809                     eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
2810                     mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
2811             assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2812         }
2813     }
2814 
validateScanSettings(@ullable String hiddenSsid)2815     private void validateScanSettings(@Nullable String hiddenSsid) {
2816         ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue();
2817         assertNotNull(scanSettings);
2818         assertEquals(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, scanSettings.band);
2819         assertEquals(WifiScanner.TYPE_HIGH_ACCURACY, scanSettings.type);
2820         assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, scanSettings.reportEvents);
2821         if (hiddenSsid == null) {
2822             assertNull(scanSettings.hiddenNetworks);
2823         } else {
2824             assertNotNull(scanSettings.hiddenNetworks);
2825             assertNotNull(scanSettings.hiddenNetworks[0]);
2826             assertEquals(scanSettings.hiddenNetworks[0].ssid, addEnclosingQuotes(hiddenSsid));
2827         }
2828         WorkSource workSource = mWorkSourceArgumentCaptor.getValue();
2829         assertNotNull(workSource);
2830         assertEquals(TEST_UID_1, workSource.get(0));
2831     }
2832 
2833     class WifiConfigMatcher implements ArgumentMatcher<WifiConfiguration> {
2834         private final WifiConfiguration mConfig;
2835 
WifiConfigMatcher(WifiConfiguration config)2836         WifiConfigMatcher(WifiConfiguration config) {
2837             assertNotNull(config);
2838             mConfig = config;
2839         }
2840 
2841         @Override
matches(WifiConfiguration otherConfig)2842         public boolean matches(WifiConfiguration otherConfig) {
2843             if (otherConfig == null) return false;
2844             return mConfig.configKey().equals(otherConfig.configKey());
2845         }
2846     }
2847 
validateUiStartParams(boolean expectedIsReqForSingeNetwork)2848     private void validateUiStartParams(boolean expectedIsReqForSingeNetwork) {
2849         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
2850         verify(mContext, atLeastOnce()).startActivityAsUser(
2851                 intentArgumentCaptor.capture(), eq(UserHandle.getUserHandleForUid(TEST_UID_1)));
2852         Intent intent = intentArgumentCaptor.getValue();
2853         assertNotNull(intent);
2854         assertEquals(intent.getAction(), WifiNetworkFactory.UI_START_INTENT_ACTION);
2855         assertTrue(intent.getCategories().contains(WifiNetworkFactory.UI_START_INTENT_CATEGORY));
2856         assertEquals(intent.getStringExtra(WifiNetworkFactory.UI_START_INTENT_EXTRA_APP_NAME),
2857                 TEST_APP_NAME);
2858         assertEquals(expectedIsReqForSingeNetwork, intent.getBooleanExtra(
2859                 WifiNetworkFactory.UI_START_INTENT_EXTRA_REQUEST_IS_FOR_SINGLE_NETWORK, false));
2860         assertTrue((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0);
2861         assertTrue((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
2862     }
2863 
validateConnectParams(String ssid, String bssid)2864     private void validateConnectParams(String ssid, String bssid) {
2865         ArgumentCaptor<WifiConfiguration> wifiConfigurationCaptor =
2866                 ArgumentCaptor.forClass(WifiConfiguration.class);
2867         verify(mWifiConfigManager).addOrUpdateNetwork(
2868                 wifiConfigurationCaptor.capture(), eq(TEST_UID_1), eq(TEST_PACKAGE_NAME_1));
2869         WifiConfiguration network =  wifiConfigurationCaptor.getValue();
2870         assertNotNull(network);
2871         WifiConfiguration expectedWifiConfiguration =
2872                 new WifiConfiguration(((WifiNetworkSpecifier) mNetworkRequest.networkCapabilities
2873                         .getNetworkSpecifier()).wifiConfiguration);
2874         expectedWifiConfiguration.SSID = ssid;
2875         expectedWifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
2876         expectedWifiConfiguration.BSSID = bssid;
2877         expectedWifiConfiguration.ephemeral = true;
2878         expectedWifiConfiguration.fromWifiNetworkSpecifier = true;
2879         WifiConfigurationTestUtil.assertConfigurationEqual(expectedWifiConfiguration, network);
2880     }
2881 
2882     /**
2883      * Create a test scan data for target SSID list with specified number and encryption type
2884      * @param scanResultType   network encryption type
2885      * @param nums             Number of results with different BSSIDs for one SSID
2886      * @param ssids            target SSID list
2887      */
setupScanDataSameSsidWithDiffBssid(int scanResultType, int nums, String[] ssids)2888     private void setupScanDataSameSsidWithDiffBssid(int scanResultType, int nums, String[] ssids) {
2889         String baseBssid = "11:34:56:78:90:";
2890         int[] freq = new int[nums * ssids.length];
2891         for (int i = 0; i < nums; i++) {
2892             freq[i] = 2417 + i;
2893         }
2894         mTestScanDatas = ScanTestUtil.createScanDatas(new int[][]{ freq });
2895         assertEquals(1, mTestScanDatas.length);
2896         ScanResult[] scanResults = mTestScanDatas[0].getResults();
2897         assertEquals(nums * ssids.length, scanResults.length);
2898         String caps = getScanResultCapsForType(scanResultType);
2899         for (int i = 0; i < ssids.length; i++) {
2900             for (int j = i * nums; j < (i + 1) * nums; j++) {
2901                 scanResults[j].SSID = ssids[i];
2902                 scanResults[j].BSSID = baseBssid + Integer.toHexString(16 + j);
2903                 scanResults[j].capabilities = caps;
2904                 scanResults[j].level = -45;
2905             }
2906         }
2907     }
2908 
2909     /**
2910      * Helper function for serializing configuration data to a XML block.
2911      *
2912      * @return byte[] of the XML data
2913      * @throws Exception
2914      */
serializeData()2915     private byte[] serializeData() throws Exception {
2916         final XmlSerializer out = new FastXmlSerializer();
2917         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
2918         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
2919         mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
2920         out.flush();
2921         return outputStream.toByteArray();
2922     }
2923 
2924     /**
2925      * Helper function for parsing configuration data from a XML block.
2926      *
2927      * @param data XML data to parse from
2928      * @throws Exception
2929      */
deserializeData(byte[] data)2930     private void deserializeData(byte[] data) throws Exception {
2931         final XmlPullParser in = Xml.newPullParser();
2932         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
2933         in.setInput(inputStream, StandardCharsets.UTF_8.name());
2934         mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
2935                 WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
2936                 mock(WifiConfigStoreEncryptionUtil.class));
2937     }
2938 }
2939