• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.Intent.ACTION_SCREEN_OFF;
20 import static android.content.Intent.ACTION_SCREEN_ON;
21 import static android.net.wifi.WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION;
22 import static android.net.wifi.WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_IP_PROVISIONING;
23 
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
25 import static com.android.server.wifi.WifiNetworkFactory.PERIODIC_SCAN_INTERVAL_MS;
26 import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
27 
28 import static org.junit.Assert.assertArrayEquals;
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertFalse;
31 import static org.junit.Assert.assertNotNull;
32 import static org.junit.Assert.assertTrue;
33 import static org.junit.Assert.fail;
34 import static org.junit.Assume.assumeTrue;
35 import static org.mockito.ArgumentMatchers.anyBoolean;
36 import static org.mockito.Mockito.any;
37 import static org.mockito.Mockito.anyInt;
38 import static org.mockito.Mockito.anyList;
39 import static org.mockito.Mockito.anyString;
40 import static org.mockito.Mockito.argThat;
41 import static org.mockito.Mockito.atLeastOnce;
42 import static org.mockito.Mockito.clearInvocations;
43 import static org.mockito.Mockito.doAnswer;
44 import static org.mockito.Mockito.doNothing;
45 import static org.mockito.Mockito.doThrow;
46 import static org.mockito.Mockito.eq;
47 import static org.mockito.Mockito.inOrder;
48 import static org.mockito.Mockito.lenient;
49 import static org.mockito.Mockito.mock;
50 import static org.mockito.Mockito.never;
51 import static org.mockito.Mockito.reset;
52 import static org.mockito.Mockito.times;
53 import static org.mockito.Mockito.validateMockitoUsage;
54 import static org.mockito.Mockito.verify;
55 import static org.mockito.Mockito.verifyNoMoreInteractions;
56 import static org.mockito.Mockito.when;
57 
58 import static java.lang.Math.toIntExact;
59 
60 import android.annotation.Nullable;
61 import android.app.ActivityManager;
62 import android.app.AlarmManager;
63 import android.app.AlarmManager.OnAlarmListener;
64 import android.app.AppOpsManager;
65 import android.companion.CompanionDeviceManager;
66 import android.content.BroadcastReceiver;
67 import android.content.Context;
68 import android.content.Intent;
69 import android.content.pm.ApplicationInfo;
70 import android.content.pm.PackageManager;
71 import android.content.res.Resources;
72 import android.net.ConnectivityManager;
73 import android.net.MacAddress;
74 import android.net.NetworkCapabilities;
75 import android.net.NetworkProvider;
76 import android.net.NetworkRequest;
77 import android.net.NetworkSpecifier;
78 import android.net.wifi.ILocalOnlyConnectionStatusListener;
79 import android.net.wifi.INetworkRequestMatchCallback;
80 import android.net.wifi.INetworkRequestUserSelectionCallback;
81 import android.net.wifi.ScanResult;
82 import android.net.wifi.WifiConfiguration;
83 import android.net.wifi.WifiContext;
84 import android.net.wifi.WifiManager;
85 import android.net.wifi.WifiNetworkSpecifier;
86 import android.net.wifi.WifiScanner;
87 import android.net.wifi.WifiScanner.ScanListener;
88 import android.net.wifi.WifiScanner.ScanSettings;
89 import android.net.wifi.WifiSsid;
90 import android.net.wifi.util.ScanResultUtil;
91 import android.os.IBinder;
92 import android.os.PatternMatcher;
93 import android.os.PowerManager;
94 import android.os.Process;
95 import android.os.RemoteException;
96 import android.os.UserHandle;
97 import android.os.WorkSource;
98 import android.os.test.TestLooper;
99 import android.test.suitebuilder.annotation.SmallTest;
100 import android.util.Pair;
101 import android.util.Xml;
102 
103 import com.android.internal.util.FastXmlSerializer;
104 import com.android.modules.utils.build.SdkLevel;
105 import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
106 import com.android.server.wifi.proto.nano.WifiMetricsProto;
107 import com.android.server.wifi.util.ActionListenerWrapper;
108 import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
109 import com.android.server.wifi.util.WifiPermissionsUtil;
110 import com.android.wifi.resources.R;
111 
112 import org.junit.After;
113 import org.junit.Before;
114 import org.junit.Test;
115 import org.mockito.ArgumentCaptor;
116 import org.mockito.ArgumentMatcher;
117 import org.mockito.Captor;
118 import org.mockito.InOrder;
119 import org.mockito.Mock;
120 import org.mockito.MockitoAnnotations;
121 import org.mockito.MockitoSession;
122 import org.xmlpull.v1.XmlPullParser;
123 import org.xmlpull.v1.XmlSerializer;
124 
125 import java.io.ByteArrayInputStream;
126 import java.io.ByteArrayOutputStream;
127 import java.nio.charset.StandardCharsets;
128 import java.util.Arrays;
129 import java.util.Collections;
130 import java.util.HashMap;
131 import java.util.LinkedHashSet;
132 import java.util.List;
133 import java.util.Map;
134 import java.util.Set;
135 import java.util.concurrent.TimeUnit;
136 
137 /**
138  * Unit tests for {@link com.android.server.wifi.WifiNetworkFactory}.
139  */
140 @SmallTest
141 public class WifiNetworkFactoryTest extends WifiBaseTest {
142     private static final int TEST_NETWORK_ID_1 = 104;
143     private static final int TEST_UID_1 = 10423;
144     private static final int TEST_UID_2 = 10424;
145     private static final String TEST_PACKAGE_NAME_1 = "com.test.networkrequest.1";
146     private static final String TEST_PACKAGE_NAME_2 = "com.test.networkrequest.2";
147     private static final String TEST_APP_NAME = "app";
148     private static final String TEST_SSID_1 = "test1234";
149     private static final String TEST_SSID_2 = "test12345678";
150     private static final String TEST_SSID_3 = "abc1234";
151     private static final String TEST_SSID_4 = "abc12345678";
152     private static final String TEST_BSSID_1 = "12:34:23:23:45:ac";
153     private static final String TEST_BSSID_2 = "12:34:23:32:12:67";
154     private static final String TEST_BSSID_3 = "45:34:34:12:bb:dd";
155     private static final String TEST_BSSID_4 = "45:34:34:56:ee:ff";
156     private static final String TEST_BSSID_1_2_OUI = "12:34:23:00:00:00";
157     private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
158     private static final String TEST_WPA_PRESHARED_KEY = "\"password123\"";
159 
160     @Mock WifiContext mContext;
161     @Mock Resources mResources;
162     @Mock ActivityManager mActivityManager;
163     @Mock AlarmManager mAlarmManager;
164     @Mock AppOpsManager mAppOpsManager;
165     @Mock CompanionDeviceManager mCompanionDeviceManager;
166     @Mock Clock mClock;
167     @Mock WifiInjector mWifiInjector;
168     @Mock WifiConnectivityManager mWifiConnectivityManager;
169     @Mock WifiConfigManager mWifiConfigManager;
170     @Mock WifiConfigStore mWifiConfigStore;
171     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
172     @Mock FrameworkFacade mFrameworkFacade;
173     @Mock WifiScanner mWifiScanner;
174     @Mock PackageManager mPackageManager;
175     @Mock IBinder mAppBinder;
176     @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback;
177     @Mock ConcreteClientModeManager mClientModeManager;
178     @Mock ConnectivityManager mConnectivityManager;
179     @Mock WifiMetrics mWifiMetrics;
180     @Mock WifiNative mWifiNative;
181     @Mock NetworkProvider mNetworkProvider;
182     @Mock ActiveModeWarden mActiveModeWarden;
183     @Mock ConnectHelper mConnectHelper;
184     @Mock PowerManager mPowerManager;
185     @Mock ClientModeImplMonitor mCmiMonitor;
186     @Mock MultiInternetManager mMultiInternetManager;
187     @Mock ILocalOnlyConnectionStatusListener mLocalOnlyConnectionStatusListener;
188     private @Mock IBinder mBinder;
189     private @Mock ClientModeManager mPrimaryClientModeManager;
190     private @Mock WifiGlobals mWifiGlobals;
191     private MockitoSession mStaticMockSession = null;
192     NetworkCapabilities mNetworkCapabilities;
193     TestLooper mLooper;
194     NetworkRequest mNetworkRequest;
195     WifiScanner.ScanData[] mTestScanDatas;
196     WifiConfiguration mSelectedNetwork;
197     ArgumentCaptor<ScanSettings> mScanSettingsArgumentCaptor =
198             ArgumentCaptor.forClass(ScanSettings.class);
199     ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor =
200             ArgumentCaptor.forClass(WorkSource.class);
201     ArgumentCaptor<INetworkRequestUserSelectionCallback> mNetworkRequestUserSelectionCallback =
202             ArgumentCaptor.forClass(INetworkRequestUserSelectionCallback.class);
203     ArgumentCaptor<OnAlarmListener> mPeriodicScanListenerArgumentCaptor =
204             ArgumentCaptor.forClass(OnAlarmListener.class);
205     ArgumentCaptor<OnAlarmListener> mConnectionTimeoutAlarmListenerArgumentCaptor =
206             ArgumentCaptor.forClass(OnAlarmListener.class);
207     ArgumentCaptor<ScanListener> mScanListenerArgumentCaptor =
208             ArgumentCaptor.forClass(ScanListener.class);
209     ArgumentCaptor<ActionListenerWrapper> mConnectListenerArgumentCaptor =
210             ArgumentCaptor.forClass(ActionListenerWrapper.class);
211     ArgumentCaptor<ActiveModeWarden.ModeChangeCallback> mModeChangeCallbackCaptor =
212             ArgumentCaptor.forClass(ActiveModeWarden.ModeChangeCallback.class);
213     @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
214     @Captor ArgumentCaptor<ClientModeImplListener> mCmiListenerCaptor;
215     InOrder mInOrder;
216 
217     private WifiNetworkFactory mWifiNetworkFactory;
218     private NetworkRequestStoreData.DataSource mDataSource;
219     private NetworkRequestStoreData mNetworkRequestStoreData;
220 
221     /**
222      * Setup the mocks.
223      */
224     @Before
setUp()225     public void setUp() throws Exception {
226         MockitoAnnotations.initMocks(this);
227         mStaticMockSession = mockitoSession()
228                 .mockStatic(WifiInjector.class)
229                 .startMocking();
230         lenient().when(WifiInjector.getInstance()).thenReturn(mWifiInjector);
231 
232         mLooper = new TestLooper();
233         mNetworkCapabilities = new NetworkCapabilities();
234         mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
235         if (SdkLevel.isAtLeastS()) {
236             // NOT_VCN_MANAGED is not part of default network capabilities and needs to be manually
237             // added for non-VCN-underlying network factory/agent implementations.
238             mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
239         }
240         mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
241         mTestScanDatas = ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 } });
242 
243         when(mContext.getResources()).thenReturn(mResources);
244         when(mContext.getPackageManager()).thenReturn(mPackageManager);
245         when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
246                 .thenReturn(mConnectivityManager);
247         when(mContext.getSystemService(eq(ConnectivityManager.class)))
248                 .thenReturn(mConnectivityManager);
249         when(mContext.getSystemService(CompanionDeviceManager.class))
250                 .thenReturn(mCompanionDeviceManager);
251         when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
252         when(mResources.getBoolean(
253                 eq(R.bool.config_wifiUseHalApiToDisableFwRoaming)))
254                 .thenReturn(true);
255         when(mResources.getBoolean(
256                 eq(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)))
257                 .thenReturn(false);
258         when(mResources.getInteger(R.integer.config_wifiNetworkSpecifierMaxPreferredChannels))
259                 .thenReturn(5);
260         when(mPackageManager.getNameForUid(TEST_UID_1)).thenReturn(TEST_PACKAGE_NAME_1);
261         when(mPackageManager.getNameForUid(TEST_UID_2)).thenReturn(TEST_PACKAGE_NAME_2);
262         when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), any()))
263                 .thenReturn(new ApplicationInfo());
264         when(mPackageManager.getApplicationLabel(any())).thenReturn(TEST_APP_NAME);
265         mockPackageImportance(TEST_PACKAGE_NAME_1, true, false);
266         mockPackageImportance(TEST_PACKAGE_NAME_2, true, false);
267         when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
268         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
269         when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
270         when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
271         when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true);
272         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
273                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID_1));
274         when(mWifiScanner.getSingleScanResults()).thenReturn(Collections.emptyList());
275         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
276 
277         when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(true);
278         when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
279         when(mPrimaryClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
280         doAnswer(invocation -> {
281             Object[] args = invocation.getArguments();
282             ActiveModeWarden.ExternalClientModeManagerRequestListener requestListener =
283                     (ActiveModeWarden.ExternalClientModeManagerRequestListener) args[0];
284             requestListener.onAnswer(mClientModeManager);
285             return null;
286         }).when(mActiveModeWarden).requestLocalOnlyClientModeManager(any(), any(), any(), any(),
287                 anyBoolean());
288         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
289         when(mFrameworkFacade.getSettingsWorkSource(any())).thenReturn(
290                 new WorkSource(Process.SYSTEM_UID, "system-service"));
291 
292         when(mPrimaryClientModeManager.getSupportedFeatures()).thenReturn(
293                 WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE);
294 
295         mWifiNetworkFactory = new WifiNetworkFactory(mLooper.getLooper(), mContext,
296                 mNetworkCapabilities, mActivityManager, mAlarmManager, mAppOpsManager,
297                 mClock, mWifiInjector, mWifiConnectivityManager,
298                 mWifiConfigManager, mWifiConfigStore, mWifiPermissionsUtil, mWifiMetrics,
299                 mWifiNative, mActiveModeWarden, mConnectHelper, mCmiMonitor, mFrameworkFacade,
300                 mMultiInternetManager);
301 
302         verify(mContext, atLeastOnce()).registerReceiver(
303                 mBroadcastReceiverCaptor.capture(), any(), any(), any());
304 
305         ArgumentCaptor<NetworkRequestStoreData.DataSource> dataSourceArgumentCaptor =
306                 ArgumentCaptor.forClass(NetworkRequestStoreData.DataSource.class);
307         verify(mWifiInjector).makeNetworkRequestStoreData(dataSourceArgumentCaptor.capture());
308         mDataSource = dataSourceArgumentCaptor.getValue();
309         assertNotNull(mDataSource);
310         mNetworkRequestStoreData = new NetworkRequestStoreData(mDataSource);
311 
312         verify(mActiveModeWarden).registerModeChangeCallback(
313                 mModeChangeCallbackCaptor.capture());
314         assertNotNull(mModeChangeCallbackCaptor.getValue());
315 
316         // Register factory with connectivity manager.
317         mWifiNetworkFactory.register();
318         ArgumentCaptor<NetworkProvider> networkProviderArgumentCaptor =
319                 ArgumentCaptor.forClass(NetworkProvider.class);
320         verify(mConnectivityManager).registerNetworkProvider(
321                 networkProviderArgumentCaptor.capture());
322         mNetworkProvider = networkProviderArgumentCaptor.getValue();
323         assertNotNull(mNetworkProvider);
324         mLooper.dispatchAll();
325 
326         mNetworkRequest = new NetworkRequest.Builder()
327                 .setCapabilities(mNetworkCapabilities)
328                 .build();
329 
330         // Setup with wifi on.
331         mWifiNetworkFactory.enableVerboseLogging(true);
332         when(mLocalOnlyConnectionStatusListener.asBinder()).thenReturn(mBinder);
333     }
334 
335     /**
336      * Called after each test
337      */
338     @After
cleanup()339     public void cleanup() {
340         validateMockitoUsage();
341         if (null != mStaticMockSession) {
342             mStaticMockSession.finishMocking();
343         }
344     }
345 
mockPackageImportance(String packageName, boolean isFgAppOrService, boolean isFgApp)346     private void mockPackageImportance(String packageName, boolean isFgAppOrService,
347             boolean isFgApp) {
348         when(mFrameworkFacade.isRequestFromForegroundAppOrService(any(), eq(packageName)))
349                 .thenReturn(isFgAppOrService);
350         when(mFrameworkFacade.isRequestFromForegroundApp(any(), eq(packageName)))
351                 .thenReturn(isFgApp);
352     }
353 
354     /**
355      * Validates handling of needNetworkFor.
356      */
357     @Test
testHandleNetworkRequestWithNoSpecifier()358     public void testHandleNetworkRequestWithNoSpecifier() {
359         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
360         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
361 
362         // First network request should turn on auto-join.
363         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(true);
364         assertTrue(mWifiNetworkFactory.hasConnectionRequests());
365 
366         // Subsequent ones should do nothing.
367         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
368         verifyNoMoreInteractions(mWifiConnectivityManager);
369     }
370 
371     /**
372      * Validates handling of releaseNetwork.
373      */
374     @Test
testHandleNetworkReleaseWithNoSpecifier()375     public void testHandleNetworkReleaseWithNoSpecifier() {
376         // Release network with out a corresponding request should be ignored.
377         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
378         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
379 
380         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
381         assertTrue(mWifiNetworkFactory.hasConnectionRequests());
382         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(true);
383 
384         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
385         assertFalse(mWifiNetworkFactory.hasConnectionRequests());
386         verify(mWifiConnectivityManager).setTrustedConnectionAllowed(false);
387     }
388 
389     /**
390      * Validates handling of acceptNetwork for requests with no network specifier.
391      */
392     @Test
testHandleAcceptNetworkRequestWithNoSpecifier()393     public void testHandleAcceptNetworkRequestWithNoSpecifier() {
394         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
395     }
396 
397     /**
398      * Validates handling of acceptNetwork with an unsupported network specifier
399      */
400     @Test
testHandleAcceptNetworkRequestFromWithUnsupportedSpecifier()401     public void testHandleAcceptNetworkRequestFromWithUnsupportedSpecifier() throws Exception {
402         // Attach an unsupported specifier.
403         mNetworkCapabilities.setNetworkSpecifier(mock(NetworkSpecifier.class));
404         mNetworkRequest = new NetworkRequest.Builder()
405                 .setCapabilities(mNetworkCapabilities)
406                 .build();
407 
408         // request should be rejected, but not released.
409         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
410         mLooper.dispatchAll();
411         verify(mConnectivityManager, never()).declareNetworkRequestUnfulfillable(any());
412     }
413 
414     /**
415      * Validates that requests that specify a frequency band are rejected.
416      */
417     @Test
testHandleAcceptNetworkRequestWithBand()418     public void testHandleAcceptNetworkRequestWithBand() throws Exception {
419         WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
420                 .setBand(ScanResult.WIFI_BAND_5_GHZ)
421                 .build();
422         mNetworkCapabilities.setNetworkSpecifier(specifier);
423         mNetworkRequest = new NetworkRequest.Builder()
424                 .setCapabilities(mNetworkCapabilities)
425                 .build();
426 
427         // request should be rejected and released.
428         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
429         mLooper.dispatchAll();
430         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(any());
431     }
432 
433     /**
434      * Validates handling of acceptNetwork with a network specifier with invalid uid/package name.
435      */
436     @Test
testHandleAcceptNetworkRequestFromWithInvalidWifiNetworkSpecifier()437     public void testHandleAcceptNetworkRequestFromWithInvalidWifiNetworkSpecifier()
438             throws Exception {
439         mockPackageImportance(TEST_PACKAGE_NAME_1, false, false);
440 
441         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1))
442                 .thenReturn(true);
443         doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
444 
445         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
446 
447         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
448         mLooper.dispatchAll();
449         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
450     }
451 
452     /**
453      * Validates handling of acceptNetwork with a network specifier with internet capability.
454      */
455     @Test
testHandleAcceptNetworkRequestFromWithInternetCapability()456     public void testHandleAcceptNetworkRequestFromWithInternetCapability() throws Exception {
457         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
458 
459         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
460         mNetworkRequest.networkCapabilities.addCapability(
461                 NetworkCapabilities.NET_CAPABILITY_INTERNET);
462 
463         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
464         mLooper.dispatchAll();
465         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
466     }
467 
468     /**
469      * Validates handling of acceptNetwork with a network specifier from a non foreground
470      * app/service.
471      */
472     @Test
testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier()473     public void testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier() throws Exception {
474         mockPackageImportance(TEST_PACKAGE_NAME_1, false, false);
475 
476         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
477 
478         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
479         mLooper.dispatchAll();
480         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
481     }
482 
483     @Test
testNetworkRequestFromGuestUserWithSpecifier()484     public void testNetworkRequestFromGuestUserWithSpecifier() {
485         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
486         when(mWifiPermissionsUtil.isGuestUser()).thenReturn(true);
487         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
488 
489         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
490         mLooper.dispatchAll();
491         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
492     }
493 
494     /**
495      * Validates handling of acceptNetwork with a network specifier from a foreground
496      * app.
497      */
498     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifier()499     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifier() {
500         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
501 
502         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
503 
504         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
505     }
506 
507     /**
508      * Validates handling of acceptNetwork with a network specifier from apps holding
509      * NETWORK_SETTINGS.
510      */
511     @Test
testHandleAcceptNetworkRequestFromNetworkSettingAppWithSpecifier()512     public void testHandleAcceptNetworkRequestFromNetworkSettingAppWithSpecifier() {
513         mockPackageImportance(TEST_PACKAGE_NAME_1, false, false);
514         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1))
515                 .thenReturn(true);
516 
517         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
518 
519         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
520     }
521 
522     /**
523      * Validates handling of acceptNetwork with a network specifier from a foreground
524      * app.
525      */
526     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgSvc()527     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgSvc() {
528         mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
529 
530         // Handle request 1.
531         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
532         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
533 
534         // Make request 2 which will be accepted because a fg app request can
535         // override a fg service request.
536         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
537         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
538     }
539 
540     /**
541      * Validates handling of acceptNetwork with a network specifier from a foreground
542      * app.
543      */
544     @Test
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc()545     public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc() {
546 
547         // Handle request 1.
548         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
549         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
550 
551         // Make request 2 which will be accepted because a fg service request can
552         // override an existing fg service request.
553         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
554         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
555     }
556 
557     /**
558      * Validates handling of acceptNetwork with a network specifier from a foreground
559      * app.
560      */
561     @Test
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgApp()562     public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgApp() {
563         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
564         mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
565 
566         // Handle request 1.
567         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
568         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
569 
570         // Make request 2 which will be accepted because a fg app request can
571         // override an existing fg app request.
572         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
573         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
574     }
575 
576     /**
577      * Validates handling of acceptNetwork with a network specifier from a foreground
578      * service when we're in the midst of processing a request from a foreground app.
579      */
580     @Test
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgApp()581     public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgApp()
582             throws Exception {
583         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
584 
585         // Handle request 1.
586         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
587         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
588 
589         // Make request 2 which will be rejected because a fg service request cannot
590         // override a fg app request.
591         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
592         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
593         mLooper.dispatchAll();
594         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
595     }
596 
597     /**
598      * Validates handling of acceptNetwork with a network specifier from a foreground
599      * service when we're in the midst of processing the same request from a foreground app.
600      * Caused by the app transitioning to a fg service & connectivity stack triggering a
601      * re-evaluation.
602      */
603     @Test
604     public void
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithSamePendingRequestFromFgApp()605             testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithSamePendingRequestFromFgApp()
606             throws Exception {
607         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
608 
609         // Handle request 1.
610         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
611         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
612 
613         // Resend the request from a fg service (should be accepted since it is already being
614         // processed).
615         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
616         mLooper.dispatchAll();
617     }
618 
619     /**
620      * Validates handling of acceptNetwork with a network specifier from a foreground
621      * app when we're connected to a request from a foreground app.
622      */
623     @Test
624     public void
testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithConnectedRequestFromFgApp()625             testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithConnectedRequestFromFgApp()
626             throws Exception {
627         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
628         mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
629 
630         // Connect to request 1
631         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
632         // Send network connection success indication.
633         assertNotNull(mSelectedNetwork);
634         mWifiNetworkFactory.handleConnectionAttemptEnded(
635                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1,
636                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
637 
638         // Make request 2 which will be accepted because a fg app request can
639         // override an existing fg app request.
640         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
641         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
642     }
643 
644     /**
645      * Validates handling of acceptNetwork with a network specifier from a foreground
646      * service when we're connected to a request from a foreground app.
647      */
648     @Test
649     public void
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithConnectedRequestFromFgApp()650             testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithConnectedRequestFromFgApp()
651             throws Exception {
652         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
653 
654         // Connect to request 1
655         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
656         // Send network connection success indication.
657         assertNotNull(mSelectedNetwork);
658         mWifiNetworkFactory.handleConnectionAttemptEnded(
659                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1,
660                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
661 
662         // Make request 2 which will be rejected because a fg service request cannot
663         // override a fg app request.
664         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
665         assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
666         mLooper.dispatchAll();
667         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
668     }
669 
670     /**
671      * Validates handling of acceptNetwork with a network specifier from a foreground
672      * service when we're in the connected to the same request from a foreground app.
673      * Caused by the app transitioning to a fg service & connectivity stack triggering a
674      * re-evaluation.
675      */
676     @Test
677     public void
testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithSameConnectedRequestFromFgApp()678             testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithSameConnectedRequestFromFgApp()
679             throws Exception {
680         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
681 
682         // Connect to request 1
683         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
684         // Send network connection success indication.
685         assertNotNull(mSelectedNetwork);
686         mWifiNetworkFactory.handleConnectionAttemptEnded(
687                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1,
688                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
689 
690         // Resend the request from a fg service (should be accepted since it is already connected).
691         assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
692     }
693 
694     /**
695      * Verify handling of new network request with network specifier.
696      */
697     @Test
testHandleNetworkRequestWithSpecifier()698     public void testHandleNetworkRequestWithSpecifier() {
699         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
700         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
701 
702         // Verify UI start.
703         validateUiStartParams(true);
704 
705         // Verify scan settings.
706         verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), any(),
707                 mWorkSourceArgumentCaptor.capture());
708         validateScanSettings(null, new int[0]);
709 
710         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
711     }
712 
713     /**
714      * Validates handling of new network request with unsupported network specifier.
715      */
716     @Test
testHandleNetworkRequestWithUnsupportedSpecifier()717     public void testHandleNetworkRequestWithUnsupportedSpecifier() throws Exception {
718         // Attach an unsupported specifier.
719         mNetworkCapabilities.setNetworkSpecifier(mock(NetworkSpecifier.class));
720         mNetworkRequest = new NetworkRequest.Builder()
721                 .setCapabilities(mNetworkCapabilities)
722                 .build();
723 
724         // Ignore the request, but don't release it.
725         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
726         mLooper.dispatchAll();
727         verify(mConnectivityManager, never()).declareNetworkRequestUnfulfillable(any());
728 
729         verifyNoMoreInteractions(mWifiScanner, mWifiConnectivityManager, mWifiMetrics);
730     }
731 
732     /**
733      * Validates handling of new network request with network specifier with internet capability.
734      */
735     @Test
testHandleNetworkRequestWithSpecifierAndInternetCapability()736     public void testHandleNetworkRequestWithSpecifierAndInternetCapability() throws Exception {
737         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
738         mNetworkRequest.networkCapabilities.addCapability(
739                 NetworkCapabilities.NET_CAPABILITY_INTERNET);
740 
741         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
742         mLooper.dispatchAll();
743         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
744     }
745 
746     /**
747      * Verify handling of new network request with network specifier for a hidden network.
748      */
749     @Test
testHandleNetworkRequestWithSpecifierForHiddenNetwork()750     public void testHandleNetworkRequestWithSpecifierForHiddenNetwork() {
751         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0]);
752         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
753 
754         // Verify UI start.
755         validateUiStartParams(true);
756 
757         // Verify scan settings.
758         verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), any(),
759                 mWorkSourceArgumentCaptor.capture());
760         validateScanSettings(
761                 ((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
762                         .ssidPatternMatcher.getPath(), new int[0]);
763 
764         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
765     }
766 
767     /**
768      * Verify handling of new network request with network specifier for a non-hidden network
769      * after processing a previous hidden network requst.
770      * Validates that the scan settings was properly reset between the 2 request
771      * {@link ScanSettings#hiddenNetworks}
772      */
773     @Test
testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest()774     public void testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest() {
775         // Hidden request 1.
776         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0]);
777         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
778         // Verify scan settings.
779         verify(mWifiScanner, times(1)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
780                 any(), mWorkSourceArgumentCaptor.capture());
781         validateScanSettings(
782                 ((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
783                         .ssidPatternMatcher.getPath(), new int[0]);
784 
785         // Release request 1.
786         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
787 
788         // Regular request 2.
789         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
790         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
791         // Verify scan settings.
792         verify(mWifiScanner, times(2)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
793                 any(), mWorkSourceArgumentCaptor.capture());
794         validateScanSettings(null, new int[0]);
795 
796         verify(mWifiMetrics, times(2)).incrementNetworkRequestApiNumRequest();
797     }
798 
799     /**
800      * Verify handling of release of the active network request with network specifier.
801      */
802     @Test
testHandleNetworkReleaseWithSpecifier()803     public void testHandleNetworkReleaseWithSpecifier() {
804         // Make a generic request first to ensure that we re-enable auto-join after release.
805         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
806 
807         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
808 
809         // Make the network request with specifier.
810         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
811         verify(mWifiScanner).startScan(any(), any(), any(), any());
812 
813         // Release the network request.
814         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
815         // Verify that we did not trigger a disconnect because we've not yet connected.
816         verify(mClientModeManager, never()).disconnect();
817 
818         verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
819     }
820 
821     /**
822      * Verify the periodic scan to find a network matching the network specifier.
823      * Simulates the case where the network is not found in any of the scan results.
824      */
825     @Test
testPeriodicScanNetworkRequestWithSpecifier()826     public void testPeriodicScanNetworkRequestWithSpecifier() {
827         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
828         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
829 
830         verifyPeriodicScans(0,
831                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
832                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
833                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
834                 PERIODIC_SCAN_INTERVAL_MS);    // 10s
835     }
836 
837     /**
838      * Verify the periodic scan back off to find a network matching the network specifier
839      * is cancelled when the active network request is released.
840      */
841     @Test
testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier()842     public void testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier() {
843         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
844         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
845 
846         verifyPeriodicScans(0,
847                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
848                 PERIODIC_SCAN_INTERVAL_MS);    // 10s
849 
850         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
851         // Cancel the alarm set for the next scan.
852         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
853     }
854 
855     /**
856      * Verify the periodic scan back off to find a network matching the network specifier
857      * is cancelled when the user selects a network.
858      */
859     @Test
testPeriodicScanCancelOnUserSelectNetwork()860     public void testPeriodicScanCancelOnUserSelectNetwork() throws Exception {
861         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
862         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
863 
864         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
865         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
866                 mNetworkRequestUserSelectionCallback.capture());
867 
868         verifyPeriodicScans(0,
869                 PERIODIC_SCAN_INTERVAL_MS,     // 10s
870                 PERIODIC_SCAN_INTERVAL_MS);    // 10s
871 
872         // Now trigger user selection to one of the network.
873         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
874         mSelectedNetwork.SSID = "\"" + TEST_SSID_1 + "\"";
875         sendUserSelectionSelect(mNetworkRequestUserSelectionCallback.getValue(), mSelectedNetwork);
876         mLooper.dispatchAll();
877 
878         // Cancel the alarm set for the next scan.
879         verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
880     }
881 
882 
883     /**
884      * Verify callback registration/unregistration.
885      */
886     @Test
testHandleCallbackRegistrationAndUnregistration()887     public void testHandleCallbackRegistrationAndUnregistration() throws Exception {
888         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
889         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
890 
891         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
892 
893         //Ensure that we register the user selection callback using the newly registered callback.
894         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
895                 any(INetworkRequestUserSelectionCallback.class));
896 
897         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
898         verify(mNetworkRequestMatchCallback, atLeastOnce()).asBinder();
899 
900         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
901     }
902 
903     /**
904      * Verify callback registration when the active request has already been released..
905      */
906     @Test
testHandleCallbackRegistrationWithNoActiveRequest()907     public void testHandleCallbackRegistrationWithNoActiveRequest() throws Exception {
908         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
909         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
910         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
911 
912         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
913 
914         //Ensure that we trigger the onAbort callback & nothing else.
915         verify(mNetworkRequestMatchCallback).onAbort();
916 
917         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
918 
919         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
920     }
921 
922     /**
923      * Verify network specifier matching for a specifier containing a specific SSID match using
924      * 4 WPA_PSK scan results, each with unique SSID.
925      */
926     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatch()927     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatch() throws Exception {
928         // Setup scan data for open networks.
929         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
930                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
931 
932         // Setup network specifier for open networks.
933         PatternMatcher ssidPatternMatch =
934                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
935         Pair<MacAddress, MacAddress> bssidPatternMatch =
936                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
937         WifiConfiguration wifiConfiguration = new WifiConfiguration();
938         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
939         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
940         attachWifiNetworkSpecifierAndAppInfo(
941                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
942                 TEST_PACKAGE_NAME_1, new int[0]);
943         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
944 
945         validateUiStartParams(true);
946 
947         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
948 
949         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
950 
951         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
952                 ArgumentCaptor.forClass(List.class);
953         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
954 
955         assertNotNull(matchedScanResultsCaptor.getValue());
956         // We only expect 1 network match in this case.
957         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
958 
959         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
960                 matchedScanResultsCaptor.getValue().size());
961     }
962 
963     /**
964      * Verify network specifier matching for a specifier containing a specific SSID match using
965      * 4 WPA_PSK + SAE transition scan results, each with unique SSID.
966      */
967     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchForSaeTransitionScanResult()968     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchForSaeTransitionScanResult()
969             throws Exception {
970         setupScanData(SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION,
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(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
978         WifiConfiguration wifiConfiguration = new WifiConfiguration();
979         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
980         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
981         attachWifiNetworkSpecifierAndAppInfo(
982                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
983                 TEST_PACKAGE_NAME_1, new int[0]);
984         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
985 
986         validateUiStartParams(true);
987 
988         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
989 
990         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
991 
992         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
993                 ArgumentCaptor.forClass(List.class);
994         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
995 
996         assertNotNull(matchedScanResultsCaptor.getValue());
997         // We only expect 1 network match in this case.
998         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
999 
1000         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
1001                 matchedScanResultsCaptor.getValue().size());
1002     }
1003 
1004     /**
1005      * Verify network specifier matching for a specifier containing a Prefix SSID match using
1006      * 4 open scan results, each with unique SSID.
1007      */
1008     @Test
testNetworkSpecifierMatchSuccessUsingPrefixSsidMatch()1009     public void testNetworkSpecifierMatchSuccessUsingPrefixSsidMatch() throws Exception {
1010         // Setup scan data for open networks.
1011         setupScanData(SCAN_RESULT_TYPE_OPEN,
1012                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1013 
1014         // Setup network specifier for open networks.
1015         PatternMatcher ssidPatternMatch =
1016                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX);
1017         Pair<MacAddress, MacAddress> bssidPatternMatch =
1018                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1019         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1020         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
1021         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1022         attachWifiNetworkSpecifierAndAppInfo(
1023                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1024                 TEST_PACKAGE_NAME_1, new int[0]);
1025         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1026 
1027         validateUiStartParams(false);
1028 
1029         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1030 
1031         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1032 
1033         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
1034                 ArgumentCaptor.forClass(List.class);
1035         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
1036 
1037         assertNotNull(matchedScanResultsCaptor.getValue());
1038         // We expect 2 scan result matches in this case.
1039         validateScanResults(matchedScanResultsCaptor.getValue(),
1040                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1]);
1041 
1042         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
1043                 matchedScanResultsCaptor.getValue().size());
1044     }
1045 
1046     /**
1047      * Verify network specifier matching for a specifier containing a specific BSSID match using
1048      * 4 WPA_PSK scan results, each with unique SSID.
1049      */
1050     @Test
testNetworkSpecifierMatchSuccessUsingLiteralBssidMatch()1051     public void testNetworkSpecifierMatchSuccessUsingLiteralBssidMatch() throws Exception {
1052         // Setup scan data for open networks.
1053         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1054                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1055 
1056         // Setup network specifier for open networks.
1057         PatternMatcher ssidPatternMatch =
1058                 new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
1059         Pair<MacAddress, MacAddress> bssidPatternMatch =
1060                 Pair.create(MacAddress.fromString(TEST_BSSID_1), MacAddress.BROADCAST_ADDRESS);
1061         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1062         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1063         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1064         attachWifiNetworkSpecifierAndAppInfo(
1065                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1066                 TEST_PACKAGE_NAME_1, new int[0]);
1067         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1068 
1069         validateUiStartParams(true);
1070 
1071         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1072 
1073         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1074 
1075         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
1076                 ArgumentCaptor.forClass(List.class);
1077         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
1078 
1079         assertNotNull(matchedScanResultsCaptor.getValue());
1080         // We only expect 1 scan result match in this case.
1081         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
1082 
1083         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
1084                 matchedScanResultsCaptor.getValue().size());
1085     }
1086 
1087     /**
1088      * Verify network specifier matching for a specifier containing a prefix BSSID match using
1089      * 4 WPA_EAP scan results, each with unique SSID.
1090      */
1091     @Test
testNetworkSpecifierMatchSuccessUsingOuiPrefixBssidMatch()1092     public void testNetworkSpecifierMatchSuccessUsingOuiPrefixBssidMatch() throws Exception {
1093         // Setup scan data for open networks.
1094         setupScanData(SCAN_RESULT_TYPE_WPA_EAP,
1095                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1096 
1097         // Setup network specifier for open networks.
1098         PatternMatcher ssidPatternMatch =
1099                 new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
1100         Pair<MacAddress, MacAddress> bssidPatternMatch =
1101                 Pair.create(MacAddress.fromString(TEST_BSSID_1_2_OUI),
1102                         MacAddress.fromString(TEST_BSSID_OUI_MASK));
1103         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1104         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
1105         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1106         attachWifiNetworkSpecifierAndAppInfo(
1107                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1108                 TEST_PACKAGE_NAME_1, new int[0]);
1109         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1110 
1111         validateUiStartParams(false);
1112 
1113         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1114 
1115         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1116 
1117         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
1118                 ArgumentCaptor.forClass(List.class);
1119         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
1120 
1121         assertNotNull(matchedScanResultsCaptor.getValue());
1122         // We expect 2 scan result matches in this case.
1123         validateScanResults(matchedScanResultsCaptor.getValue(),
1124                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1]);
1125 
1126         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
1127                 matchedScanResultsCaptor.getValue().size());
1128     }
1129 
1130     /**
1131      * Verify network specifier matching for a specifier containing a specific SSID match using
1132      * 4 WPA_PSK scan results, 3 of which have the same SSID.
1133      */
1134     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchWithMultipleBssidMatches()1135     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchWithMultipleBssidMatches()
1136             throws Exception {
1137         // Setup scan data for open networks.
1138         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1139                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_1, TEST_SSID_2);
1140 
1141         // Setup network specifier for open networks.
1142         PatternMatcher ssidPatternMatch =
1143                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1144         Pair<MacAddress, MacAddress> bssidPatternMatch =
1145                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1146         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1147         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1148         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1149         attachWifiNetworkSpecifierAndAppInfo(
1150                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1151                 TEST_PACKAGE_NAME_1, new int[0]);
1152         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1153 
1154         validateUiStartParams(true);
1155 
1156         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1157 
1158         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1159 
1160         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
1161                 ArgumentCaptor.forClass(List.class);
1162         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
1163 
1164         assertNotNull(matchedScanResultsCaptor.getValue());
1165         // We expect 3 scan result matches in this case.
1166         validateScanResults(matchedScanResultsCaptor.getValue(),
1167                 mTestScanDatas[0].getResults()[0], mTestScanDatas[0].getResults()[1],
1168                 mTestScanDatas[0].getResults()[2]);
1169 
1170         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
1171                 matchedScanResultsCaptor.getValue().size());
1172     }
1173 
1174     /**
1175      * Verify network specifier match failure for a specifier containing a specific SSID match using
1176      * 4 WPA_PSK scan results, 2 of which SSID_1 and the other 2 SSID_2. But, none of the scan
1177      * results' SSID match the one requested in the specifier.
1178      */
1179     @Test
testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenSsidNotFound()1180     public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenSsidNotFound()
1181             throws Exception {
1182         // Setup scan data for open networks.
1183         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1184                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_2, TEST_SSID_2);
1185 
1186         // Setup network specifier for open networks.
1187         PatternMatcher ssidPatternMatch =
1188                 new PatternMatcher(TEST_SSID_3, PatternMatcher.PATTERN_LITERAL);
1189         Pair<MacAddress, MacAddress> bssidPatternMatch =
1190                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1191         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1192         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1193         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1194         attachWifiNetworkSpecifierAndAppInfo(
1195                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1196                 TEST_PACKAGE_NAME_1, new int[0]);
1197         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1198 
1199         validateUiStartParams(true);
1200 
1201         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1202 
1203         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1204 
1205         // We expect no network match in this case.
1206         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
1207 
1208         // Don't increment metrics until we have a match
1209         verify(mWifiMetrics, never()).incrementNetworkRequestApiMatchSizeHistogram(anyInt());
1210     }
1211 
1212     /**
1213      * Verify network specifier match failure for a specifier containing a specific SSID match using
1214      * 4 open scan results, each with unique SSID. But, none of the scan
1215      * results' key mgmt match the one requested in the specifier.
1216      */
1217     @Test
testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenKeyMgmtDiffers()1218     public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenKeyMgmtDiffers()
1219             throws Exception {
1220         // Setup scan data for open networks.
1221         setupScanData(SCAN_RESULT_TYPE_OPEN,
1222                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1223 
1224         // Setup network specifier for open networks.
1225         PatternMatcher ssidPatternMatch =
1226                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1227         Pair<MacAddress, MacAddress> bssidPatternMatch =
1228                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1229         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1230         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1231         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1232         attachWifiNetworkSpecifierAndAppInfo(
1233                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1234                 TEST_PACKAGE_NAME_1, new int[0]);
1235         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1236 
1237         validateUiStartParams(true);
1238 
1239         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1240 
1241         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1242 
1243         // We expect no network match in this case.
1244         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
1245     }
1246 
1247     /**
1248      * Verify handling of stale user selection (previous request released).
1249      */
1250     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkWithoutActiveRequest()1251     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkWithoutActiveRequest()
1252             throws Exception {
1253         sendNetworkRequestAndSetupForUserSelection();
1254 
1255         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1256                 mNetworkRequestUserSelectionCallback.getValue();
1257         assertNotNull(networkRequestUserSelectionCallback);
1258 
1259         // Now release the active network request.
1260         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1261 
1262         // Now trigger user selection to some network.
1263         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1264         sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
1265         mLooper.dispatchAll();
1266 
1267         // Verify we did not attempt to trigger a connection or disable connectivity manager.
1268         verifyNoMoreInteractions(mClientModeManager, mWifiConnectivityManager);
1269     }
1270 
1271     /**
1272      * Verify handling of stale user selection (new request replacing the previous request).
1273      */
1274     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkWithDifferentActiveRequest()1275     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkWithDifferentActiveRequest()
1276             throws Exception {
1277         sendNetworkRequestAndSetupForUserSelection();
1278 
1279         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1280                 mNetworkRequestUserSelectionCallback.getValue();
1281         assertNotNull(networkRequestUserSelectionCallback);
1282 
1283         // Now send another network request.
1284         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
1285         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1286 
1287         // Now trigger user selection to some network.
1288         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1289         sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
1290         mLooper.dispatchAll();
1291 
1292         // verify(mWifiConnectivityManager, times(2)).isStaConcurrencyForMultiInternetEnabled();
1293         // Verify we did not attempt to trigger a connection or disable connectivity manager.
1294         verifyNoMoreInteractions(mClientModeManager, mWifiConnectivityManager, mWifiConfigManager);
1295     }
1296 
1297     /**
1298      * Verify handling of user selection to trigger connection to a network.
1299      */
1300     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetwork()1301     public void testNetworkSpecifierHandleUserSelectionConnectToNetwork() throws Exception {
1302         sendNetworkRequestAndSetupForUserSelection();
1303 
1304         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1305                 mNetworkRequestUserSelectionCallback.getValue();
1306         assertNotNull(networkRequestUserSelectionCallback);
1307 
1308         // Now trigger user selection to one of the network.
1309         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
1310         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1311         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1312         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1313         mLooper.dispatchAll();
1314 
1315         // Cancel periodic scans.
1316         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1317         // Disable connectivity manager
1318         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1319 
1320         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1321         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1322                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1323 
1324         verify(mClientModeManager).disconnect();
1325         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1326                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1327                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1328     }
1329 
1330     /**
1331      * Verify when number of user approved access points exceed the capacity, framework should trim
1332      * the Set by removing the least recently used elements.
1333      */
1334     @Test
testNetworkSpecifierHandleUserSelectionConnectToNetworkExceedApprovedListCapacity()1335     public void testNetworkSpecifierHandleUserSelectionConnectToNetworkExceedApprovedListCapacity()
1336             throws Exception {
1337         int userApproveAccessPointCapacity = WifiNetworkFactory.NUM_OF_ACCESS_POINT_LIMIT_PER_APP;
1338         int numOfApPerSsid = userApproveAccessPointCapacity / 2 + 1;
1339         String[] testIds = new String[]{TEST_SSID_1, TEST_SSID_2};
1340 
1341         // Setup up scan data
1342         setupScanDataSameSsidWithDiffBssid(SCAN_RESULT_TYPE_WPA_PSK, numOfApPerSsid, testIds);
1343 
1344         // Setup network specifier for WPA-PSK networks.
1345         PatternMatcher ssidPatternMatch =
1346                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX);
1347         Pair<MacAddress, MacAddress> bssidPatternMatch =
1348                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1349         WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork();
1350         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1351         attachWifiNetworkSpecifierAndAppInfo(
1352                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1353                 TEST_PACKAGE_NAME_1, new int[0]);
1354         // request network, trigger scan and get matched set.
1355         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1356 
1357         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1358         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1359                 mNetworkRequestUserSelectionCallback.capture());
1360 
1361         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1362 
1363         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1364                 mNetworkRequestUserSelectionCallback.getValue();
1365         assertNotNull(networkRequestUserSelectionCallback);
1366 
1367         // Now trigger user selection to one of the network.
1368         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1369         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1370         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1371         mLooper.dispatchAll();
1372 
1373         // Verifier num of Approved access points.
1374         assertEquals(mWifiNetworkFactory.mUserApprovedAccessPointMap
1375                 .get(TEST_PACKAGE_NAME_1).size(), numOfApPerSsid);
1376 
1377         // Now trigger user selection to another network with different SSID.
1378         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1379         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[numOfApPerSsid].SSID + "\"";
1380         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1381         mLooper.dispatchAll();
1382 
1383         // Verify triggered trim when user Approved Access Points exceed capacity.
1384         Set<AccessPoint> userApprovedAccessPoints = mWifiNetworkFactory.mUserApprovedAccessPointMap
1385                 .get(TEST_PACKAGE_NAME_1);
1386         assertEquals(userApprovedAccessPoints.size(), userApproveAccessPointCapacity);
1387         long numOfSsid1Aps = userApprovedAccessPoints
1388                 .stream()
1389                 .filter(a->a.ssid.equals(TEST_SSID_1))
1390                 .count();
1391         assertEquals(numOfSsid1Aps, userApproveAccessPointCapacity - numOfApPerSsid);
1392     }
1393 
1394     /**
1395      * Verify handling of user selection to trigger connection to an existing saved network.
1396      */
1397     @Test
testNetworkSpecifierHandleUserSelectionConnectToExistingSavedNetwork()1398     public void testNetworkSpecifierHandleUserSelectionConnectToExistingSavedNetwork()
1399             throws Exception {
1400         sendNetworkRequestAndSetupForUserSelection();
1401 
1402         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1403                 mNetworkRequestUserSelectionCallback.getValue();
1404         assertNotNull(networkRequestUserSelectionCallback);
1405 
1406         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1407         mSelectedNetwork.SSID = "\"" + mTestScanDatas[0].getResults()[0].SSID + "\"";
1408         mSelectedNetwork.shared = false;
1409 
1410         // Have a saved network with the same configuration.
1411         WifiConfiguration matchingSavedNetwork = new WifiConfiguration(mSelectedNetwork);
1412         matchingSavedNetwork.networkId = TEST_NETWORK_ID_1;
1413         when(mWifiConfigManager.getConfiguredNetwork(mSelectedNetwork.getProfileKey()))
1414                 .thenReturn(matchingSavedNetwork);
1415 
1416         // Now trigger user selection to one of the network.
1417         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1418         mLooper.dispatchAll();
1419 
1420         // Cancel periodic scans.
1421         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1422         // Disable connectivity manager
1423         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1424 
1425         // verify we don't try to add the network to WifiConfigManager.
1426         verify(mWifiConfigManager, never())
1427                 .addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false));
1428 
1429         verify(mClientModeManager).disconnect();
1430         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1431                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1432                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1433     }
1434 
1435     /**
1436      * Verify handling of user selection to trigger connection to a network. Ensure we fill
1437      * up the BSSID field.
1438      */
1439     @Test
1440     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkUsingLiteralSsidAndBssidMatch()1441             testNetworkSpecifierHandleUserSelectionConnectToNetworkUsingLiteralSsidAndBssidMatch()
1442             throws Exception {
1443         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1444                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1445 
1446         // Make a specific AP request.
1447         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
1448         PatternMatcher ssidPatternMatch =
1449                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1450         Pair<MacAddress, MacAddress> bssidPatternMatch =
1451                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
1452                         MacAddress.BROADCAST_ADDRESS);
1453         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1454         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1455         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1456         attachWifiNetworkSpecifierAndAppInfo(
1457                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1458                 TEST_PACKAGE_NAME_1, new int[0]);
1459         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1460         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1461         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1462                 mNetworkRequestUserSelectionCallback.capture());
1463         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1464 
1465         // Now trigger user selection to the network.
1466         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1467         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1468         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1469                 mNetworkRequestUserSelectionCallback.getValue();
1470         assertNotNull(networkRequestUserSelectionCallback);
1471         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1472         mLooper.dispatchAll();
1473 
1474         // Verify WifiConfiguration params.
1475         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1476         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1477                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1478 
1479         verify(mClientModeManager).disconnect();
1480         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1481                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1482                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1483     }
1484 
1485     /**
1486      * Verify handling of user selection to trigger connection to a network. Ensure we fill
1487      * up the BSSID field with scan result for highest RSSI.
1488      */
1489     @Test
1490     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkMultipleBssidMatches()1491             testNetworkSpecifierHandleUserSelectionConnectToNetworkMultipleBssidMatches()
1492             throws Exception {
1493         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
1494                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_1, TEST_SSID_4);
1495 
1496         // Make a ssid pattern request which matches 3 scan results - 0, 1, 2.
1497         PatternMatcher ssidPatternMatch =
1498                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1499         Pair<MacAddress, MacAddress> bssidPatternMatch =
1500                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
1501         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1502         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1503         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1504         attachWifiNetworkSpecifierAndAppInfo(
1505                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1506                 TEST_PACKAGE_NAME_1, new int[0]);
1507         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1508         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1509         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1510                 mNetworkRequestUserSelectionCallback.capture());
1511         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
1512 
1513         // Scan result 2 has the highest RSSI, so that should be picked.
1514         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[2];
1515 
1516         // Now trigger user selection to the network.
1517         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1518         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1519         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1520                 mNetworkRequestUserSelectionCallback.getValue();
1521         assertNotNull(networkRequestUserSelectionCallback);
1522         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1523         mLooper.dispatchAll();
1524 
1525         // Verify WifiConfiguration params.
1526         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1527         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1528                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1529 
1530         verify(mClientModeManager).disconnect();
1531         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1532                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1533                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1534     }
1535 
1536     /**
1537      * Verify handling of user selection to trigger connection to a network when the selected bssid
1538      * is no longer seen in scan results within the cache expiry duration. Ensure we fill up the
1539      * BSSID field.
1540      */
1541     @Test
1542     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkMissingBssidInLatest()1543             testNetworkSpecifierHandleUserSelectionConnectToNetworkMissingBssidInLatest()
1544             throws Exception {
1545         WifiScanner.ScanData[] scanDatas1 =
1546                 ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
1547         setupScanData(scanDatas1, SCAN_RESULT_TYPE_WPA_PSK,
1548                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1549         // Modify the next set of scan results to simulate missing |TEST_SSID_1| ScanResult.
1550         WifiScanner.ScanData[] scanDatas2 =
1551                 ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
1552         setupScanData(scanDatas2, SCAN_RESULT_TYPE_WPA_PSK,
1553                 TEST_SSID_2, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1554 
1555         // Make a specific AP request.
1556         ScanResult matchingScanResult = scanDatas1[0].getResults()[0];
1557         PatternMatcher ssidPatternMatch =
1558                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1559         Pair<MacAddress, MacAddress> bssidPatternMatch =
1560                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
1561                         MacAddress.BROADCAST_ADDRESS);
1562         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1563         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1564         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1565         attachWifiNetworkSpecifierAndAppInfo(
1566                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1567                 TEST_PACKAGE_NAME_1, new int[0]);
1568         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1569         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1570         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1571                 mNetworkRequestUserSelectionCallback.capture());
1572         verifyPeriodicScans(
1573                 0L,
1574                 new PeriodicScanParams(0, scanDatas1),
1575                 new PeriodicScanParams(PERIODIC_SCAN_INTERVAL_MS, scanDatas2));
1576 
1577         // Now trigger user selection to the network.
1578         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1579         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1580         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1581                 mNetworkRequestUserSelectionCallback.getValue();
1582         assertNotNull(networkRequestUserSelectionCallback);
1583         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1584         mLooper.dispatchAll();
1585 
1586         // Verify WifiConfiguration params.
1587         validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
1588         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1589                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1590 
1591         verify(mClientModeManager).disconnect();
1592         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1593                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1594                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1595     }
1596 
1597     /**
1598      * Verify handling of user selection to trigger connection to a network when the selected bssid
1599      * is no longer seen in scan results beyond the cache expiry duration. Ensure we don't fill up
1600      * the BSSID field.
1601      */
1602     @Test
1603     public void
testNetworkSpecifierHandleUserSelectionConnectToNetworkStaleMissingBssidInLatest()1604             testNetworkSpecifierHandleUserSelectionConnectToNetworkStaleMissingBssidInLatest()
1605             throws Exception {
1606         WifiScanner.ScanData[] scanDatas1 =
1607                 ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
1608         setupScanData(scanDatas1, SCAN_RESULT_TYPE_WPA_PSK,
1609                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1610         // Modify the next set of scan results to simulate missing |TEST_SSID_1| ScanResult.
1611         WifiScanner.ScanData[] scanDatas2 =
1612                 ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
1613         setupScanData(scanDatas2, SCAN_RESULT_TYPE_WPA_PSK,
1614                 TEST_SSID_2, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
1615 
1616         // Make a specific AP request.
1617         ScanResult matchingScanResult = scanDatas1[0].getResults()[0];
1618         PatternMatcher ssidPatternMatch =
1619                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
1620         Pair<MacAddress, MacAddress> bssidPatternMatch =
1621                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
1622                         MacAddress.BROADCAST_ADDRESS);
1623         WifiConfiguration wifiConfiguration = new WifiConfiguration();
1624         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
1625         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
1626         attachWifiNetworkSpecifierAndAppInfo(
1627                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
1628                 TEST_PACKAGE_NAME_1, new int[0]);
1629         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
1630         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
1631         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1632                 mNetworkRequestUserSelectionCallback.capture());
1633 
1634         long nowMs = WifiNetworkFactory.CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS + 1;
1635         scanDatas2[0].getResults()[0].timestamp = nowMs;
1636         scanDatas2[0].getResults()[1].timestamp = nowMs;
1637         scanDatas2[0].getResults()[2].timestamp = nowMs;
1638         scanDatas2[0].getResults()[3].timestamp = nowMs;
1639         verifyPeriodicScans(
1640                 nowMs,
1641                 new PeriodicScanParams(0, scanDatas1),
1642                 new PeriodicScanParams(PERIODIC_SCAN_INTERVAL_MS, scanDatas2));
1643 
1644         // Now trigger user selection to the network.
1645         mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
1646         mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
1647         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1648                 mNetworkRequestUserSelectionCallback.getValue();
1649         assertNotNull(networkRequestUserSelectionCallback);
1650         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
1651         mLooper.dispatchAll();
1652 
1653         // Verify WifiConfiguration params.
1654         validateConnectParams(mSelectedNetwork.SSID, null);
1655         verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
1656                 eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
1657 
1658         verify(mClientModeManager).disconnect();
1659         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
1660                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
1661                 mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
1662     }
1663 
1664     /**
1665      * Verify handling of user selection to reject the request.
1666      */
1667     @Test
testNetworkSpecifierHandleUserSelectionReject()1668     public void testNetworkSpecifierHandleUserSelectionReject() throws Exception {
1669         sendNetworkRequestAndSetupForUserSelection();
1670 
1671         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
1672                 mNetworkRequestUserSelectionCallback.getValue();
1673         assertNotNull(networkRequestUserSelectionCallback);
1674 
1675         // Now trigger user rejection.
1676         networkRequestUserSelectionCallback.reject();
1677         mLooper.dispatchAll();
1678 
1679         // Cancel periodic scans.
1680         verify(mAlarmManager).cancel(any(OnAlarmListener.class));
1681         // Verify we reset the network request handling.
1682         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1683 
1684         verify(mWifiMetrics).incrementNetworkRequestApiNumUserReject();
1685 
1686         // Verify we did not attempt to trigger a connection.
1687         verifyNoMoreInteractions(mClientModeManager, mWifiConfigManager);
1688     }
1689 
1690     /**
1691      * Verify handling of connection timeout.
1692      * The timeouts should trigger connection retries until we hit the max.
1693      */
1694     @Test
testNetworkSpecifierHandleConnectionTimeout()1695     public void testNetworkSpecifierHandleConnectionTimeout() throws Exception {
1696         sendNetworkRequestAndSetupForConnectionStatus();
1697 
1698         // Simulate connection timeout beyond the retry limit to trigger the failure handling.
1699         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1700             mConnectionTimeoutAlarmListenerArgumentCaptor.getValue().onAlarm();
1701             mLooper.dispatchAll();
1702         }
1703 
1704         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1705         validateConnectionRetryAttempts(true);
1706 
1707         // Fail the request after all the retries are exhausted.
1708         verify(mNetworkRequestMatchCallback).onAbort();
1709         // Verify that we sent the connection failure callback.
1710         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1711                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1712         // Verify we reset the network request handling.
1713         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1714         verify(mActiveModeWarden).removeClientModeManager(any());
1715         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1716     }
1717 
1718     /**
1719      * Verify handling of connection trigger failure.
1720      * The trigger failures should trigger connection retries until we hit the max.
1721      */
1722     @Test
testNetworkSpecifierHandleConnectionTriggerFailure()1723     public void testNetworkSpecifierHandleConnectionTriggerFailure() throws Exception {
1724         sendNetworkRequestAndSetupForConnectionStatus();
1725 
1726         // Send failure message beyond the retry limit to trigger the failure handling.
1727         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1728             assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1729             mConnectListenerArgumentCaptor.getValue()
1730                     .sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
1731         }
1732         mLooper.dispatchAll();
1733 
1734         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1735         validateConnectionRetryAttempts(false);
1736 
1737         // Fail the request after all the retries are exhausted.
1738         verify(mNetworkRequestMatchCallback).onAbort();
1739         // Verify that we sent the connection failure callback.
1740         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1741                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1742         // verify we canceled the timeout alarm.
1743         mInOrder.verify(mAlarmManager).cancel(
1744                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1745         // Verify we reset the network request handling.
1746         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1747         verify(mActiveModeWarden).removeClientModeManager(any());
1748         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1749     }
1750 
1751     /**
1752      * Verify handling of connection failure.
1753      * The connection failures should trigger connection retries until we hit the max.
1754      */
1755     @Test
testNetworkSpecifierHandleConnectionFailure()1756     public void testNetworkSpecifierHandleConnectionFailure() throws Exception {
1757         sendNetworkRequestAndSetupForConnectionStatus();
1758 
1759         assertNotNull(mSelectedNetwork);
1760         mWifiNetworkFactory.addLocalOnlyConnectionStatusListener(mLocalOnlyConnectionStatusListener,
1761                 TEST_PACKAGE_NAME_1, null);
1762 
1763         // Send network connection failure indication beyond the retry limit to trigger the failure
1764         // handling.
1765         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1766             mWifiNetworkFactory.handleConnectionAttemptEnded(
1767                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork, TEST_BSSID_1,
1768                     WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1769             mLooper.dispatchAll();
1770         }
1771 
1772         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1773         validateConnectionRetryAttempts(false);
1774 
1775         verify(mNetworkRequestMatchCallback).onAbort();
1776         // Verify that we sent the connection failure callback.
1777         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1778                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1779         // verify we canceled the timeout alarm.
1780         mInOrder.verify(mAlarmManager).cancel(
1781                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1782         // Verify we reset the network request handling.
1783         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1784         verify(mActiveModeWarden).removeClientModeManager(any());
1785         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1786         verify(mLocalOnlyConnectionStatusListener).onConnectionStatus(
1787                 eq((WifiNetworkSpecifier) mNetworkRequest.getNetworkSpecifier()),
1788                 eq(STATUS_LOCAL_ONLY_CONNECTION_FAILURE_IP_PROVISIONING));
1789     }
1790 
1791     /**
1792      * Verify handling of authentication failure.
1793      * The connection failures should not trigger connection retries.
1794      */
1795     @Test
testNetworkSpecifierHandleAuthFailure()1796     public void testNetworkSpecifierHandleAuthFailure() throws Exception {
1797         sendNetworkRequestAndSetupForConnectionStatus();
1798 
1799         assertNotNull(mSelectedNetwork);
1800         mWifiNetworkFactory.addLocalOnlyConnectionStatusListener(mLocalOnlyConnectionStatusListener,
1801                 TEST_PACKAGE_NAME_1, null);
1802 
1803         mWifiNetworkFactory.handleConnectionAttemptEnded(
1804                     WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, mSelectedNetwork,
1805                 TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD);
1806         mLooper.dispatchAll();
1807 
1808         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1809 
1810         verify(mNetworkRequestMatchCallback).onAbort();
1811         // Verify that we sent the connection failure callback.
1812         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1813                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1814         // verify we canceled the timeout alarm.
1815         mInOrder.verify(mAlarmManager).cancel(
1816                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1817         // Verify we reset the network request handling.
1818         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1819         verify(mActiveModeWarden).removeClientModeManager(any());
1820         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1821         verify(mLocalOnlyConnectionStatusListener).onConnectionStatus(
1822                 eq((WifiNetworkSpecifier) mNetworkRequest.getNetworkSpecifier()),
1823                 eq(STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION));
1824     }
1825 
1826     /**
1827      * Verify handling of connection failure to a different network.
1828      */
1829     @Test
testNetworkSpecifierHandleConnectionFailureToWrongNetwork()1830     public void testNetworkSpecifierHandleConnectionFailureToWrongNetwork() throws Exception {
1831         sendNetworkRequestAndSetupForConnectionStatus();
1832 
1833         // Send network connection failure to a different network indication.
1834         assertNotNull(mSelectedNetwork);
1835         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
1836         connectedNetwork.SSID = TEST_SSID_2;
1837         mWifiNetworkFactory.handleConnectionAttemptEnded(
1838                 WifiMetrics.ConnectionEvent.FAILURE_DHCP, connectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1839 
1840         // Verify that we did not send the connection failure callback.
1841         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectFailure(any());
1842         // verify we canceled the timeout alarm.
1843         verify(mAlarmManager, never())
1844                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1845         // Verify we don't reset the network request handling.
1846         verify(mWifiConnectivityManager, never())
1847                 .setSpecificNetworkRequestInProgress(false);
1848 
1849         // Send network connection failure indication beyond the retry limit to trigger the failure
1850         // handling.
1851         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1852             mWifiNetworkFactory.handleConnectionAttemptEnded(
1853                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1854             mLooper.dispatchAll();
1855         }
1856 
1857         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1858         validateConnectionRetryAttempts(false);
1859 
1860         // Verify that we sent the connection failure callback.
1861         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1862                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1863         // verify we canceled the timeout alarm.
1864         mInOrder.verify(mAlarmManager).cancel(
1865                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1866         // Verify we reset the network request handling.
1867         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1868         verify(mActiveModeWarden).removeClientModeManager(any());
1869         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1870     }
1871 
1872     /**
1873      * Verify handling of connection failure to a different bssid.
1874      */
1875     @Test
testNetworkSpecifierHandleConnectionFailureToWrongBssid()1876     public void testNetworkSpecifierHandleConnectionFailureToWrongBssid() throws Exception {
1877         sendNetworkRequestAndSetupForConnectionStatus();
1878 
1879         // Send network connection failure to a different bssid indication.
1880         assertNotNull(mSelectedNetwork);
1881         mWifiNetworkFactory.handleConnectionAttemptEnded(
1882                 WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork, TEST_BSSID_2, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1883 
1884         // Verify that we did not send the connection failure callback.
1885         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectFailure(any());
1886         // verify we canceled the timeout alarm.
1887         verify(mAlarmManager, never())
1888                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1889         // Verify we don't reset the network request handling.
1890         verify(mWifiConnectivityManager, never())
1891                 .setSpecificNetworkRequestInProgress(false);
1892 
1893         // Send network connection failure indication beyond the retry limit to trigger the failure
1894         // handling.
1895         for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
1896             mWifiNetworkFactory.handleConnectionAttemptEnded(
1897                     WifiMetrics.ConnectionEvent.FAILURE_DHCP, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1898             mLooper.dispatchAll();
1899         }
1900 
1901         mInOrder = inOrder(mAlarmManager, mClientModeManager, mConnectHelper);
1902         validateConnectionRetryAttempts(false);
1903 
1904         // Verify that we sent the connection failure callback.
1905         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1906                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1907         // verify we canceled the timeout alarm.
1908         mInOrder.verify(mAlarmManager).cancel(
1909                 mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1910         // Verify we reset the network request handling.
1911         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1912         verify(mActiveModeWarden).removeClientModeManager(any());
1913         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
1914     }
1915 
1916     /**
1917      * Verify handling of connection success.
1918      */
1919     @Test
testNetworkSpecifierHandleConnectionSuccess()1920     public void testNetworkSpecifierHandleConnectionSuccess() throws Exception {
1921         sendNetworkRequestAndSetupForConnectionStatus();
1922 
1923         // Send network connection success indication.
1924         assertNotNull(mSelectedNetwork);
1925         mWifiNetworkFactory.handleConnectionAttemptEnded(
1926                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1927 
1928         // Verify that we sent the connection success callback.
1929         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1930                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1931         // verify we canceled the timeout alarm.
1932         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1933         // Verify we disabled fw roaming.
1934         verify(mClientModeManager).enableRoaming(false);
1935 
1936         // Now release the active network request.
1937         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1938 
1939         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
1940         // Ensure that we toggle auto-join state.
1941         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1942         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1943         verify(mClientModeManager).enableRoaming(true);
1944     }
1945 
1946     /**
1947      * Verify handling of connection success.
1948      */
1949     @Test
testNetworkSpecifierHandleConnectionSuccessWhenUseHalApiIsDisabled()1950     public void testNetworkSpecifierHandleConnectionSuccessWhenUseHalApiIsDisabled()
1951             throws Exception {
1952         when(mResources.getBoolean(
1953                 eq(R.bool.config_wifiUseHalApiToDisableFwRoaming)))
1954                 .thenReturn(false);
1955         sendNetworkRequestAndSetupForConnectionStatus();
1956 
1957         // Send network connection success indication.
1958         assertNotNull(mSelectedNetwork);
1959         mWifiNetworkFactory.handleConnectionAttemptEnded(
1960                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1961 
1962         // Verify that we sent the connection success callback.
1963         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1964                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1965         // verify we canceled the timeout alarm.
1966         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1967         // Verify we disabled fw roaming.
1968         verify(mClientModeManager, never()).enableRoaming(false);
1969 
1970         // Now release the active network request.
1971         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
1972 
1973         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
1974         // Ensure that we toggle auto-join state.
1975         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
1976         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
1977         verify(mClientModeManager, never()).enableRoaming(true);
1978     }
1979 
1980     /**
1981      * Verify handling of connection success.
1982      */
1983     @Test
testNetworkSpecifierHandleConnectionSuccessOnSecondaryCmm()1984     public void testNetworkSpecifierHandleConnectionSuccessOnSecondaryCmm()
1985             throws Exception {
1986         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY);
1987         sendNetworkRequestAndSetupForConnectionStatus();
1988 
1989         // Send network connection success indication.
1990         assertNotNull(mSelectedNetwork);
1991         mWifiNetworkFactory.handleConnectionAttemptEnded(
1992                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
1993 
1994         // Verify that we sent the connection success callback.
1995         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1996                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
1997         // verify we canceled the timeout alarm.
1998         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
1999         // Verify we disabled fw roaming.
2000         verify(mClientModeManager).enableRoaming(false);
2001 
2002         // Now release the active network request.
2003         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2004 
2005         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnSecondaryIface();
2006         // Ensure that we toggle auto-join state even for the secondary CMM.
2007         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2008         verify(mClientModeManager).enableRoaming(true);
2009     }
2010 
2011     /**
2012      * Verify handling of connection success and disconnection
2013      */
2014     @Test
testNetworkSpecifierHandleConnectionSuccessOnSecondaryCmmAndDisconnectFromAp()2015     public void testNetworkSpecifierHandleConnectionSuccessOnSecondaryCmmAndDisconnectFromAp()
2016             throws Exception {
2017         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY);
2018         sendNetworkRequestAndSetupForConnectionStatus();
2019 
2020         // Send network connection success indication.
2021         assertNotNull(mSelectedNetwork);
2022         mWifiNetworkFactory.handleConnectionAttemptEnded(
2023                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2024 
2025         // Verify that we sent the connection success callback.
2026         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2027                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2028         // verify we canceled the timeout alarm.
2029         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2030         // Verify we disabled fw roaming.
2031         verify(mClientModeManager).enableRoaming(false);
2032         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnSecondaryIface();
2033 
2034         // Disconnect from AP
2035         mWifiNetworkFactory.handleConnectionAttemptEnded(
2036                 WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION, mSelectedNetwork,
2037                 TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2038 
2039 
2040         // Verify framework will clean up for the connected network.
2041         verify(mCmiMonitor).unregisterListener(any());
2042         verify(mActiveModeWarden).removeClientModeManager(mClientModeManager);
2043         // Ensure that we toggle auto-join state even for the secondary CMM.
2044         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2045         verify(mClientModeManager).enableRoaming(true);
2046         assertEquals(0, mWifiNetworkFactory
2047                 .getSpecificNetworkRequestUids(mSelectedNetwork, TEST_BSSID_1).size());
2048     }
2049 
2050     /**
2051      * Verify that we ignore connection success events after the first one (may be triggered by a
2052      * roam event)
2053      */
2054     @Test
testNetworkSpecifierDuplicateHandleConnectionSuccess()2055     public void testNetworkSpecifierDuplicateHandleConnectionSuccess() throws Exception {
2056         sendNetworkRequestAndSetupForConnectionStatus();
2057 
2058         // Send network connection success indication.
2059         assertNotNull(mSelectedNetwork);
2060         mWifiNetworkFactory.handleConnectionAttemptEnded(
2061                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2062 
2063         // Verify that we sent the connection success callback.
2064         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2065                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2066         // verify we canceled the timeout alarm.
2067         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2068 
2069         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
2070         verify(mNetworkRequestMatchCallback, atLeastOnce()).asBinder();
2071 
2072         // Send second network connection success indication which should be ignored.
2073         mWifiNetworkFactory.handleConnectionAttemptEnded(
2074                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2075 
2076         verifyNoMoreInteractions(mNetworkRequestMatchCallback);
2077     }
2078 
2079     /**
2080      * Verify handling of connection success to a different network.
2081      */
2082     @Test
testNetworkSpecifierHandleConnectionSuccessToWrongNetwork()2083     public void testNetworkSpecifierHandleConnectionSuccessToWrongNetwork() throws Exception {
2084         sendNetworkRequestAndSetupForConnectionStatus();
2085 
2086         // Send network connection success to a different network indication.
2087         assertNotNull(mSelectedNetwork);
2088         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
2089         connectedNetwork.SSID = TEST_SSID_2;
2090         mWifiNetworkFactory.handleConnectionAttemptEnded(
2091                 WifiMetrics.ConnectionEvent.FAILURE_NONE, connectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2092 
2093         // verify that we did not send out the success callback and did not stop the alarm timeout.
2094         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectSuccess(any());
2095         verify(mAlarmManager, never())
2096                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2097 
2098         // Send network connection success to the correct network indication.
2099         mWifiNetworkFactory.handleConnectionAttemptEnded(
2100                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2101 
2102         // Verify that we sent the connection success callback.
2103         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2104                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2105         // verify we canceled the timeout alarm.
2106         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2107     }
2108 
2109     /**
2110      * Verify handling of connection success to a different BSSID.
2111      */
2112     @Test
testNetworkSpecifierHandleConnectionSuccessToWrongBssid()2113     public void testNetworkSpecifierHandleConnectionSuccessToWrongBssid() throws Exception {
2114         sendNetworkRequestAndSetupForConnectionStatus();
2115 
2116         // Send network connection success to a different network indication.
2117         assertNotNull(mSelectedNetwork);
2118         mWifiNetworkFactory.handleConnectionAttemptEnded(
2119                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_2, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2120 
2121         // verify that we did not send out the success callback and did not stop the alarm timeout.
2122         verify(mNetworkRequestMatchCallback, never()).onUserSelectionConnectSuccess(any());
2123         verify(mAlarmManager, never())
2124                 .cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2125 
2126         // Send network connection success to the correct network indication.
2127         mWifiNetworkFactory.handleConnectionAttemptEnded(
2128                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2129 
2130         // Verify that we sent the connection success callback.
2131         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2132                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2133         // verify we canceled the timeout alarm.
2134         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2135     }
2136 
2137     /**
2138      * Verify handling of request release after starting connection to the network.
2139      */
2140     @Test
testHandleNetworkReleaseWithSpecifierAfterConnectionStart()2141     public void testHandleNetworkReleaseWithSpecifierAfterConnectionStart() throws Exception {
2142         sendNetworkRequestAndSetupForConnectionStatus();
2143 
2144         assertNotNull(mSelectedNetwork);
2145 
2146         // Now release the network request.
2147         WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
2148         wcmNetwork.networkId = TEST_NETWORK_ID_1;
2149         wcmNetwork.creatorUid = TEST_UID_1;
2150         wcmNetwork.creatorName = TEST_PACKAGE_NAME_1;
2151         wcmNetwork.shared = false;
2152         wcmNetwork.fromWifiNetworkSpecifier = true;
2153         wcmNetwork.ephemeral = true;
2154         when(mWifiConfigManager.getConfiguredNetwork(wcmNetwork.getProfileKey()))
2155                 .thenReturn(wcmNetwork);
2156         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2157         // verify we canceled the timeout alarm.
2158         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2159         // Verify that we triggered a disconnect.
2160         verify(mClientModeManager, times(2)).disconnect();
2161         verify(mWifiConfigManager).removeNetwork(
2162                 TEST_NETWORK_ID_1, TEST_UID_1, TEST_PACKAGE_NAME_1);
2163         // Re-enable connectivity manager .
2164         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2165         verify(mActiveModeWarden).removeClientModeManager(any());
2166     }
2167 
2168     /**
2169      * Verify handling of request release after connecting to the network.
2170      */
2171     @Test
testHandleNetworkReleaseWithSpecifierAfterConnectionSuccess()2172     public void testHandleNetworkReleaseWithSpecifierAfterConnectionSuccess() throws Exception {
2173         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2174         sendNetworkRequestAndSetupForConnectionStatus();
2175 
2176         // Send network connection success indication.
2177         assertNotNull(mSelectedNetwork);
2178         mWifiNetworkFactory.handleConnectionAttemptEnded(
2179                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2180 
2181         // Verify that we sent the connection success callback.
2182         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2183                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2184         // verify we canceled the timeout alarm.
2185         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2186         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
2187 
2188         long connectionDurationMillis = 5665L;
2189         when(mClock.getElapsedSinceBootMillis()).thenReturn(connectionDurationMillis);
2190 
2191         // Now release the network request.
2192         WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
2193         wcmNetwork.networkId = TEST_NETWORK_ID_1;
2194         wcmNetwork.creatorUid = TEST_UID_1;
2195         wcmNetwork.creatorName = TEST_PACKAGE_NAME_1;
2196         wcmNetwork.shared = false;
2197         wcmNetwork.fromWifiNetworkSpecifier = true;
2198         wcmNetwork.ephemeral = true;
2199         when(mWifiConfigManager.getConfiguredNetwork(wcmNetwork.getProfileKey()))
2200                 .thenReturn(wcmNetwork);
2201         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2202         // Verify that we triggered a disconnect.
2203         verify(mClientModeManager, times(2)).disconnect();
2204         verify(mWifiConfigManager).removeNetwork(
2205                 TEST_NETWORK_ID_1, TEST_UID_1, TEST_PACKAGE_NAME_1);
2206         // Re-enable connectivity manager .
2207         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2208         verify(mActiveModeWarden).removeClientModeManager(any());
2209         verify(mWifiMetrics).incrementNetworkRequestApiConnectionDurationSecOnPrimaryIfaceHistogram(
2210                 toIntExact(TimeUnit.MILLISECONDS.toSeconds(connectionDurationMillis)));
2211     }
2212 
2213     /**
2214      * Verify handling of request release after connecting to the network.
2215      */
2216     @Test
testHandleNetworkReleaseWithSpecifierAfterConnectionSuccessOnSecondaryCmm()2217     public void testHandleNetworkReleaseWithSpecifierAfterConnectionSuccessOnSecondaryCmm()
2218             throws Exception {
2219         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY);
2220         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2221         sendNetworkRequestAndSetupForConnectionStatus();
2222 
2223         // Send network connection success indication.
2224         assertNotNull(mSelectedNetwork);
2225         mWifiNetworkFactory.handleConnectionAttemptEnded(
2226                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2227 
2228         // Verify that we sent the connection success callback.
2229         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2230                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2231         // verify we canceled the timeout alarm.
2232         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2233         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnSecondaryIface();
2234 
2235         // Now release the network request.
2236         long connectionDurationMillis = 5665L;
2237         when(mClock.getElapsedSinceBootMillis()).thenReturn(connectionDurationMillis);
2238         WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
2239         wcmNetwork.networkId = TEST_NETWORK_ID_1;
2240         wcmNetwork.creatorUid = TEST_UID_1;
2241         wcmNetwork.creatorName = TEST_PACKAGE_NAME_1;
2242         wcmNetwork.shared = false;
2243         wcmNetwork.fromWifiNetworkSpecifier = true;
2244         wcmNetwork.ephemeral = true;
2245         when(mWifiConfigManager.getConfiguredNetwork(wcmNetwork.getProfileKey()))
2246                 .thenReturn(wcmNetwork);
2247         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2248         // Verify that we triggered a disconnect.
2249         verify(mClientModeManager, times(2)).disconnect();
2250         verify(mWifiConfigManager).removeNetwork(
2251                 TEST_NETWORK_ID_1, TEST_UID_1, TEST_PACKAGE_NAME_1);
2252         // Re-enable connectivity manager .
2253         verify(mActiveModeWarden).removeClientModeManager(any());
2254         verify(mWifiMetrics)
2255                 .incrementNetworkRequestApiConnectionDurationSecOnSecondaryIfaceHistogram(
2256                         toIntExact(TimeUnit.MILLISECONDS.toSeconds(connectionDurationMillis)));
2257     }
2258 
2259     @Test
testMetricsUpdateForConcurrentConnections()2260     public void testMetricsUpdateForConcurrentConnections() throws Exception {
2261         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY);
2262         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
2263                 Arrays.asList(mClientModeManager));
2264 
2265         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2266         sendNetworkRequestAndSetupForConnectionStatus();
2267 
2268         // Send network connection success indication.
2269         assertNotNull(mSelectedNetwork);
2270         mWifiNetworkFactory.handleConnectionAttemptEnded(
2271                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2272 
2273         verify(mCmiMonitor).registerListener(mCmiListenerCaptor.capture());
2274 
2275         // Verify that we sent the connection success callback.
2276         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
2277                 argThat(new WifiConfigMatcher(mSelectedNetwork)));
2278         // verify we canceled the timeout alarm.
2279         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2280         verify(mWifiMetrics).incrementNetworkRequestApiNumConnectSuccessOnSecondaryIface();
2281 
2282         // Indicate secondary connection via CMI listener.
2283         when(mClientModeManager.isConnected()).thenReturn(true);
2284         mCmiListenerCaptor.getValue().onL3Connected(mClientModeManager);
2285 
2286         // Now indicate connection on the primary STA.
2287         ConcreteClientModeManager primaryCmm = mock(ConcreteClientModeManager.class);
2288         when(primaryCmm.isConnected()).thenReturn(true);
2289         when(primaryCmm.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
2290         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
2291                 Arrays.asList(mClientModeManager, primaryCmm));
2292         mCmiListenerCaptor.getValue().onL3Connected(primaryCmm);
2293 
2294         // verify metrics update for concurrent connection count.
2295         verify(mWifiMetrics).incrementNetworkRequestApiNumConcurrentConnection();
2296 
2297         // Now indicate end of connection on primary STA
2298         long primaryConnectionDurationMillis1 = 5665L;
2299         when(mClock.getElapsedSinceBootMillis()).thenReturn(primaryConnectionDurationMillis1);
2300         when(primaryCmm.isConnected()).thenReturn(false);
2301         mCmiListenerCaptor.getValue().onConnectionEnd(primaryCmm);
2302         // verify metrics update for concurrent connection duration.
2303         verify(mWifiMetrics)
2304                 .incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(
2305                         toIntExact(TimeUnit.MILLISECONDS.toSeconds(
2306                                 primaryConnectionDurationMillis1)));
2307 
2308         // Indicate a new connection on primary STA.
2309         when(primaryCmm.isConnected()).thenReturn(true);
2310         mCmiListenerCaptor.getValue().onL3Connected(primaryCmm);
2311 
2312         // verify that we did not update metrics gain for concurrent connection count.
2313         verify(mWifiMetrics, times(1)).incrementNetworkRequestApiNumConcurrentConnection();
2314 
2315         // Now indicate end of new connection on primary STA
2316         long primaryConnectionDurationMillis2 = 5665L;
2317         when(mClock.getElapsedSinceBootMillis()).thenReturn(primaryConnectionDurationMillis2);
2318         when(primaryCmm.isConnected()).thenReturn(false);
2319         mCmiListenerCaptor.getValue().onConnectionEnd(primaryCmm);
2320         // verify metrics update for concurrent connection duration.
2321         verify(mWifiMetrics)
2322                 .incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(
2323                         toIntExact(TimeUnit.MILLISECONDS.toSeconds(
2324                                 primaryConnectionDurationMillis2)));
2325 
2326         // Now release the network request.
2327         long secondaryConnectionDurationMillis = 5665L;
2328         when(mClock.getElapsedSinceBootMillis()).thenReturn(secondaryConnectionDurationMillis);
2329         WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
2330         wcmNetwork.networkId = TEST_NETWORK_ID_1;
2331         wcmNetwork.creatorUid = TEST_UID_1;
2332         wcmNetwork.creatorName = TEST_PACKAGE_NAME_1;
2333         wcmNetwork.shared = false;
2334         wcmNetwork.fromWifiNetworkSpecifier = true;
2335         wcmNetwork.ephemeral = true;
2336         when(mWifiConfigManager.getConfiguredNetwork(wcmNetwork.getProfileKey()))
2337                 .thenReturn(wcmNetwork);
2338         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2339         // Verify that we triggered a disconnect.
2340         verify(mClientModeManager, times(2)).disconnect();
2341         verify(mWifiConfigManager).removeNetwork(
2342                 TEST_NETWORK_ID_1, TEST_UID_1, TEST_PACKAGE_NAME_1);
2343         // Re-enable connectivity manager .
2344         verify(mActiveModeWarden).removeClientModeManager(any());
2345         verify(mWifiMetrics)
2346                 .incrementNetworkRequestApiConnectionDurationSecOnSecondaryIfaceHistogram(
2347                         toIntExact(TimeUnit.MILLISECONDS.toSeconds(
2348                                 secondaryConnectionDurationMillis)));
2349     }
2350 
2351 
2352     /**
2353      * Verify we return the correct UID when processing network request with network specifier.
2354      */
2355     @Test
testHandleNetworkRequestWithSpecifierGetUid()2356     public void testHandleNetworkRequestWithSpecifierGetUid() throws Exception {
2357         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUids(
2358                 new WifiConfiguration(), "").isEmpty());
2359         assertEquals(Integer.valueOf(Process.INVALID_UID),
2360                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2361                         new WifiConfiguration(), new String()).first);
2362         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2363                 new WifiConfiguration(), new String()).second.isEmpty());
2364 
2365         sendNetworkRequestAndSetupForConnectionStatus();
2366         assertNotNull(mSelectedNetwork);
2367 
2368         // connected to a different network.
2369         WifiConfiguration connectedNetwork = new WifiConfiguration(mSelectedNetwork);
2370         connectedNetwork.SSID += "test";
2371         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUids(
2372                 new WifiConfiguration(), "").isEmpty());
2373         assertEquals(Integer.valueOf(Process.INVALID_UID),
2374                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2375                         new WifiConfiguration(), new String()).first);
2376         assertTrue(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2377                 new WifiConfiguration(), new String()).second.isEmpty());
2378 
2379         // connected to the correct network.
2380         connectedNetwork = new WifiConfiguration(mSelectedNetwork);
2381         String connectedBssid = TEST_BSSID_1;
2382         assertEquals(Set.of(TEST_UID_1),
2383                 mWifiNetworkFactory.getSpecificNetworkRequestUids(
2384                         connectedNetwork, connectedBssid));
2385         assertEquals(Integer.valueOf(TEST_UID_1),
2386                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2387                         connectedNetwork, connectedBssid).first);
2388         assertEquals(TEST_PACKAGE_NAME_1,
2389                 mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(
2390                         connectedNetwork, connectedBssid).second);
2391     }
2392 
2393     /**
2394      *  Verify handling for new network request while processing another one.
2395      */
2396     @Test
testHandleNewNetworkRequestWithSpecifierWhenAwaitingCmRetrieval()2397     public void testHandleNewNetworkRequestWithSpecifierWhenAwaitingCmRetrieval() throws Exception {
2398         doNothing().when(mActiveModeWarden).requestLocalOnlyClientModeManager(
2399                 any(), any(), any(), any(), anyBoolean());
2400         WorkSource ws = new WorkSource(TEST_UID_1, TEST_PACKAGE_NAME_1);
2401 
2402         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
2403 
2404         sendNetworkRequestAndSetupForUserSelection();
2405 
2406         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
2407                 mNetworkRequestUserSelectionCallback.getValue();
2408         assertNotNull(networkRequestUserSelectionCallback);
2409 
2410         // Now trigger user selection to one of the network.
2411         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
2412         mSelectedNetwork.SSID = "\"" + TEST_SSID_1 + "\"";
2413         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
2414         mLooper.dispatchAll();
2415 
2416         ArgumentCaptor<ActiveModeWarden.ExternalClientModeManagerRequestListener> cmListenerCaptor =
2417                 ArgumentCaptor.forClass(
2418                         ActiveModeWarden.ExternalClientModeManagerRequestListener.class);
2419         verify(mActiveModeWarden).requestLocalOnlyClientModeManager(
2420                 cmListenerCaptor.capture(), eq(ws),
2421                 eq("\"" + TEST_SSID_1 + "\""), eq(TEST_BSSID_1), eq(true));
2422         assertNotNull(cmListenerCaptor.getValue());
2423 
2424         NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
2425         // Send second request.
2426         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
2427         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2428         mLooper.dispatchAll();
2429 
2430         // Verify that we aborted the old request.
2431         verify(mNetworkRequestMatchCallback).onAbort();
2432         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(oldRequest));
2433 
2434         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
2435         verify(mNetworkRequestMatchCallback, times(2)).onUserSelectionCallbackRegistration(
2436                 mNetworkRequestUserSelectionCallback.capture());
2437 
2438         // Now trigger user selection to one of the network.
2439         networkRequestUserSelectionCallback = mNetworkRequestUserSelectionCallback.getValue();
2440         assertNotNull(networkRequestUserSelectionCallback);
2441         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
2442         mLooper.dispatchAll();
2443 
2444         // Ensure we request a new ClientModeManager.
2445         verify(mActiveModeWarden, times(2)).requestLocalOnlyClientModeManager(
2446                 any(), any(), any(), any(), anyBoolean());
2447 
2448         // Now return the CM instance for the previous request.
2449         cmListenerCaptor.getValue().onAnswer(mClientModeManager);
2450 
2451         // Ensure we continued processing the new request.
2452         verify(mClientModeManager).disconnect();
2453         verify(mConnectHelper).connectToNetwork(
2454                 eq(mClientModeManager),
2455                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
2456                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
2457     }
2458 
2459     /**
2460      *  Verify handling for new network request while processing another one.
2461      */
2462     @Test
testHandleNewNetworkRequestWithSpecifierWhenScanning()2463     public void testHandleNewNetworkRequestWithSpecifierWhenScanning() throws Exception {
2464         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
2465         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2466 
2467         // Register callback.
2468         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
2469         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(any());
2470 
2471         NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
2472         // Send second request.
2473         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
2474         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2475         mLooper.dispatchAll();
2476 
2477         verify(mNetworkRequestMatchCallback).onAbort();
2478         verify(mNetworkRequestMatchCallback, atLeastOnce()).asBinder();
2479         verify(mWifiScanner, times(2)).getSingleScanResults();
2480         verify(mWifiScanner, times(2)).startScan(any(), any(), any(), any());
2481         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(oldRequest));
2482 
2483         // Remove the stale request1 & ensure nothing happens.
2484         mWifiNetworkFactory.releaseNetworkFor(oldRequest);
2485 
2486         // verify(mWifiConnectivityManager, times(2)).isStaConcurrencyForMultiInternetEnabled();
2487         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2488                 mAlarmManager, mNetworkRequestMatchCallback);
2489 
2490         // Remove the active request2.
2491         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2492     }
2493 
2494     /**
2495      *  Verify handling for new network request while processing another one.
2496      */
2497     @Test
testHandleNewNetworkRequestWithSpecifierAfterMatch()2498     public void testHandleNewNetworkRequestWithSpecifierAfterMatch() throws Exception {
2499         sendNetworkRequestAndSetupForUserSelection();
2500         WifiNetworkSpecifier specifier1 =
2501                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2502 
2503         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
2504                 mNetworkRequestUserSelectionCallback.getValue();
2505         assertNotNull(networkRequestUserSelectionCallback);
2506 
2507         NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
2508         // Send second request.
2509         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
2510         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2511 
2512         // Ensure we don't request a new ClientModeManager.
2513         verify(mActiveModeWarden, never()).requestLocalOnlyClientModeManager(
2514                 any(), any(), any(), any(), anyBoolean());
2515 
2516         // Ignore stale callbacks.
2517         WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
2518         sendUserSelectionSelect(networkRequestUserSelectionCallback, selectedNetwork);
2519         mLooper.dispatchAll();
2520 
2521         verify(mNetworkRequestMatchCallback).onAbort();
2522         verify(mNetworkRequestMatchCallback, atLeastOnce()).asBinder();
2523         verify(mWifiScanner, times(2)).getSingleScanResults();
2524         verify(mWifiScanner, times(2)).startScan(any(), any(), any(), any());
2525         verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
2526         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(oldRequest));
2527 
2528         // Remove the stale request1 & ensure nothing happens.
2529         mWifiNetworkFactory.releaseNetworkFor(oldRequest);
2530 
2531         // verify(mWifiConnectivityManager, times(2)).isStaConcurrencyForMultiInternetEnabled();
2532         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2533                 mAlarmManager, mNetworkRequestMatchCallback);
2534 
2535         // Remove the active request2.
2536         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2537     }
2538 
2539     /**
2540      *  Verify handling for new network request while processing another one.
2541      */
2542     @Test
testHandleNewNetworkRequestWithSpecifierAfterConnect()2543     public void testHandleNewNetworkRequestWithSpecifierAfterConnect() throws Exception {
2544         sendNetworkRequestAndSetupForConnectionStatus();
2545         WifiNetworkSpecifier specifier1 =
2546                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2547 
2548         NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
2549         // Send second request.
2550         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
2551         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2552 
2553         // Ensure we don't request a new ClientModeManager.
2554         verify(mActiveModeWarden, times(1)).requestLocalOnlyClientModeManager(
2555                 any(), any(), any(), any(), anyBoolean());
2556 
2557         verify(mNetworkRequestMatchCallback).onAbort();
2558         verify(mNetworkRequestMatchCallback, atLeastOnce()).asBinder();
2559         verify(mWifiConnectivityManager, times(1)).setSpecificNetworkRequestInProgress(true);
2560         verify(mWifiScanner, times(2)).getSingleScanResults();
2561         verify(mWifiScanner, times(2)).startScan(any(), any(), any(), any());
2562         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2563         verify(mClientModeManager, times(3)).getRole();
2564 
2565         // Remove the stale request1 & ensure nothing happens.
2566         mWifiNetworkFactory.releaseNetworkFor(oldRequest);
2567 
2568         // verify(mWifiConnectivityManager, times(3)).isStaConcurrencyForMultiInternetEnabled();
2569         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2570                 mAlarmManager, mNetworkRequestMatchCallback);
2571 
2572         // Remove the active request2 & ensure auto-join is re-enabled.
2573         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2574 
2575         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2576         verify(mActiveModeWarden).removeClientModeManager(any());
2577     }
2578 
2579     /**
2580      *  Verify handling for new network request while processing another one.
2581      */
2582     @Test
testHandleNewNetworkRequestWithSpecifierAfterConnectionSuccess()2583     public void testHandleNewNetworkRequestWithSpecifierAfterConnectionSuccess() throws Exception {
2584         sendNetworkRequestAndSetupForConnectionStatus();
2585         WifiNetworkSpecifier specifier1 =
2586                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2587 
2588         // Send network connection success indication.
2589         assertNotNull(mSelectedNetwork);
2590         mWifiNetworkFactory.handleConnectionAttemptEnded(
2591                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2592         // Cancel the connection timeout.
2593         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2594         verify(mClientModeManager).enableRoaming(false);
2595 
2596         NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
2597         // Send second request.
2598         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
2599         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2600 
2601         // Ensure we do request a new ClientModeManager.
2602         verify(mActiveModeWarden, times(1)).requestLocalOnlyClientModeManager(
2603                 any(), any(), any(), any(), anyBoolean());
2604 
2605         verify(mWifiConnectivityManager, times(1)).setSpecificNetworkRequestInProgress(true);
2606         verify(mWifiScanner, times(2)).getSingleScanResults();
2607         verify(mWifiScanner, times(2)).startScan(any(), any(), any(), any());
2608         // we shouldn't disconnect until the user accepts the next request.
2609         verify(mClientModeManager, times(1)).disconnect();
2610 
2611         // Remove the connected request1 & ensure we disconnect.
2612         mWifiNetworkFactory.releaseNetworkFor(oldRequest);
2613         verify(mClientModeManager, times(2)).disconnect();
2614         verify(mClientModeManager, times(3)).getRole();
2615 
2616         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2617                 mAlarmManager);
2618 
2619         // Now remove the active request2 & ensure auto-join is re-enabled.
2620         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2621 
2622         verify(mClientModeManager, times(3)).getRole();
2623         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2624         verify(mClientModeManager).enableRoaming(true);
2625         verify(mActiveModeWarden).removeClientModeManager(any());
2626 
2627         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2628                 mAlarmManager);
2629     }
2630 
2631     /**
2632      *  Verify handling for same network request while connected to it.
2633      */
2634     @Test
testHandleSameNetworkRequestWithSpecifierAfterConnectionSuccess()2635     public void testHandleSameNetworkRequestWithSpecifierAfterConnectionSuccess() throws Exception {
2636         sendNetworkRequestAndSetupForConnectionStatus();
2637 
2638         // Send network connection success indication.
2639         assertNotNull(mSelectedNetwork);
2640         mWifiNetworkFactory.handleConnectionAttemptEnded(
2641                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2642         // Cancel the connection timeout.
2643         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2644 
2645         clearInvocations(mWifiConnectivityManager, mWifiScanner, mClientModeManager, mAlarmManager);
2646 
2647         // Send same request again (nothing should happen).
2648         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2649         mLooper.dispatchAll();
2650 
2651         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2652                 mAlarmManager);
2653     }
2654     /**
2655      *  Verify handling for new network request while processing another one.
2656      */
2657     @Test
testHandleNewNetworkRequestWithSpecifierWhichUserSelectedAfterConnectionSuccess()2658     public void testHandleNewNetworkRequestWithSpecifierWhichUserSelectedAfterConnectionSuccess()
2659             throws Exception {
2660         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
2661         WifiNetworkSpecifier specifier1 =
2662                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2663 
2664         // Send network connection success indication.
2665         assertNotNull(mSelectedNetwork);
2666         mWifiNetworkFactory.handleConnectionAttemptEnded(
2667                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2668         // Cancel the connection timeout.
2669         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2670         verify(mClientModeManager).enableRoaming(false);
2671 
2672         // Send second request & we simulate the user selecting the request & connecting to it.
2673         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager);
2674         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_2);
2675         WifiNetworkSpecifier specifier2 =
2676                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2677         assertNotNull(mSelectedNetwork);
2678         mWifiNetworkFactory.handleConnectionAttemptEnded(
2679                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_2, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2680         verify(mClientModeManager, times(2)).enableRoaming(false);
2681         // Cancel the connection timeout.
2682         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2683 
2684         // We shouldn't explicitly disconnect, the new connection attempt will implicitly disconnect
2685         // from the connected network.
2686         verify(mClientModeManager, times(2)).disconnect();
2687         verify(mClientModeManager, times(6)).getRole();
2688 
2689         // Remove the stale request1 & ensure nothing happens (because it was replaced by the
2690         // second request)
2691         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
2692         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2693 
2694         // verify(mWifiConnectivityManager, times(4)).isStaConcurrencyForMultiInternetEnabled();
2695         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2696                 mAlarmManager);
2697 
2698         // Now remove the rejected request2, ensure we disconnect & re-enable auto-join.
2699         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
2700         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2701         verify(mClientModeManager, times(3)).disconnect();
2702         verify(mClientModeManager, times(6)).getRole();
2703         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2704         verify(mClientModeManager).enableRoaming(true);
2705         verify(mActiveModeWarden).removeClientModeManager(any());
2706         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2707                 mAlarmManager);
2708     }
2709 
2710     /**
2711      *  Verify handling for new network request while processing another one.
2712      */
2713     @Test
testHandleNewNetworkRequestWithSpecifierWhichUserRejectedAfterConnectionSuccess()2714     public void testHandleNewNetworkRequestWithSpecifierWhichUserRejectedAfterConnectionSuccess()
2715             throws Exception {
2716         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
2717         WifiNetworkSpecifier specifier1 =
2718                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2719 
2720         // Send network connection success indication.
2721         assertNotNull(mSelectedNetwork);
2722         mWifiNetworkFactory.handleConnectionAttemptEnded(
2723                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
2724         // Cancel the connection timeout.
2725         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2726 
2727         // Send second request & we simulate the user rejecting the request.
2728         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager);
2729         sendNetworkRequestAndSetupForUserSelection(TEST_SSID_2, false);
2730         WifiNetworkSpecifier specifier2 =
2731                 (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
2732         mNetworkRequestUserSelectionCallback.getValue().reject();
2733         mLooper.dispatchAll();
2734         // cancel periodic scans.
2735         verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
2736         // Verify we disabled fw roaming.
2737         verify(mClientModeManager).enableRoaming(false);
2738 
2739         // we shouldn't disconnect/re-enable auto-join until the connected request is released.
2740         verify(mWifiConnectivityManager, never()).setSpecificNetworkRequestInProgress(false);
2741         verify(mClientModeManager, times(1)).disconnect();
2742 
2743         // Remove the connected request1 & ensure we disconnect & ensure auto-join is re-enabled.
2744         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
2745         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2746         verify(mClientModeManager, times(2)).disconnect();
2747         verify(mClientModeManager, times(3)).getRole();
2748         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2749         verify(mClientModeManager).enableRoaming(true);
2750         verify(mActiveModeWarden).removeClientModeManager(any());
2751 
2752         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2753                 mAlarmManager);
2754 
2755         // Now remove the rejected request2 & ensure nothing happens
2756         mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
2757         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2758 
2759         verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeManager,
2760                 mAlarmManager);
2761     }
2762 
2763     /**
2764      * Verify handling of screen state changes while triggering periodic scans to find matching
2765      * networks.
2766      */
2767     @Test
testNetworkSpecifierHandleScreenStateChangedWhileScanning()2768     public void testNetworkSpecifierHandleScreenStateChangedWhileScanning() throws Exception {
2769         sendNetworkRequestAndSetupForUserSelection();
2770 
2771         // Turn off screen.
2772         setScreenState(false);
2773 
2774         // 1. Cancel the scan timer.
2775         mInOrder.verify(mAlarmManager).cancel(
2776                 mPeriodicScanListenerArgumentCaptor.getValue());
2777         // 2. Simulate the scan results from an ongoing scan, ensure no more scans are scheduled.
2778         mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas);
2779 
2780         // Ensure no more interactions.
2781         mInOrder.verifyNoMoreInteractions();
2782 
2783         // Now, turn the screen on.
2784         setScreenState(true);
2785 
2786         // Verify that we resumed periodic scanning.
2787         mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
2788     }
2789 
2790     /**
2791      * Verify handling of screen state changes after the active network request was released.
2792      */
2793     @Test
testNetworkSpecifierHandleScreenStateChangedWithoutActiveRequest()2794     public void testNetworkSpecifierHandleScreenStateChangedWithoutActiveRequest()
2795             throws Exception {
2796         sendNetworkRequestAndSetupForUserSelection();
2797         // Now release the active network request.
2798         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2799         // Cancel the scan timer on release.
2800         mInOrder.verify(mAlarmManager).cancel(
2801                 mPeriodicScanListenerArgumentCaptor.getValue());
2802 
2803         // Turn off screen.
2804         setScreenState(false);
2805 
2806         // Now, turn the screen on.
2807         setScreenState(true);
2808 
2809         // Ensure that we did not pause or resume scanning.
2810         mInOrder.verifyNoMoreInteractions();
2811     }
2812 
2813     /**
2814      * Verify handling of screen state changes after user selected a network to connect to.
2815      */
2816     @Test
testNetworkSpecifierHandleScreenStateChangedAfterUserSelection()2817     public void testNetworkSpecifierHandleScreenStateChangedAfterUserSelection() throws Exception {
2818         sendNetworkRequestAndSetupForConnectionStatus();
2819 
2820         // Turn off screen.
2821         setScreenState(false);
2822 
2823         // Now, turn the screen on.
2824         setScreenState(true);
2825 
2826         // Ensure that we did not pause or resume scanning.
2827         mInOrder.verifyNoMoreInteractions();
2828     }
2829 
2830     /**
2831      * Verify handling of new network request with network specifier when wifi is off.
2832      * The request should be rejected immediately.
2833      */
2834     @Test
testHandleNetworkRequestWithSpecifierWhenWifiOff()2835     public void testHandleNetworkRequestWithSpecifierWhenWifiOff() {
2836         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
2837 
2838         // wifi off
2839         when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(false);
2840         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2841         verify(mWifiScanner, never()).startScan(any(), any(), any(), any());
2842 
2843         // wifi on
2844         when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(true);
2845         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2846         verify(mWifiScanner).startScan(any(), any(), any(), any());
2847     }
2848 
2849     /**
2850      *  Verify wifi toggle off when scanning.
2851      */
2852     @Test
testHandleNetworkRequestWithSpecifierWifiOffWhenScanning()2853     public void testHandleNetworkRequestWithSpecifierWifiOffWhenScanning() throws Exception {
2854         sendNetworkRequestAndSetupForUserSelection();
2855 
2856         // toggle wifi off & verify we aborted ongoing request (CMM not retrieved yet).
2857         when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(false);
2858         when(mClientModeManager.getRole()).thenReturn(null); // Role returned is null on removal.
2859         mModeChangeCallbackCaptor.getValue().onActiveModeManagerRemoved(
2860                 mock(ConcreteClientModeManager.class));
2861         mLooper.dispatchAll();
2862         verify(mNetworkRequestMatchCallback).onAbort();
2863     }
2864 
2865     /**
2866      *  Verify wifi toggle off after connection attempt is started.
2867      */
2868     @Test
testHandleNetworkRequestWithSpecifierWifiOffAfterConnect()2869     public void testHandleNetworkRequestWithSpecifierWifiOffAfterConnect() throws Exception {
2870         mWifiNetworkFactory.enableVerboseLogging(true);
2871         sendNetworkRequestAndSetupForConnectionStatus();
2872 
2873         // toggle wifi off & verify we aborted ongoing request.
2874         when(mClientModeManager.getRole()).thenReturn(null); // Role returned is null on removal.
2875         mModeChangeCallbackCaptor.getValue().onActiveModeManagerRemoved(mClientModeManager);
2876         mLooper.dispatchAll();
2877 
2878         verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
2879         verify(mNetworkRequestMatchCallback).onAbort();
2880         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
2881         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
2882         verify(mActiveModeWarden).removeClientModeManager(any());
2883     }
2884 
2885     /**
2886      * Verify handling of new network request with network specifier when wifi is off.
2887      * The request should be rejected immediately.
2888      */
2889     @Test
testFullHandleNetworkRequestWithSpecifierWhenWifiOff()2890     public void testFullHandleNetworkRequestWithSpecifierWhenWifiOff() {
2891         attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
2892 
2893         // wifi off
2894         when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(false);
2895         // Add the request, should do nothing.
2896         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2897         mLooper.dispatchAll();
2898         verify(mWifiScanner, never()).startScan(any(), any(), any(), any());
2899         verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
2900     }
2901 
2902     /**
2903      * Verify that we don't bypass user approval for a specific request for an access point that was
2904      * approved previously, but then the user forgot it sometime after.
2905      */
2906     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNForgot()2907     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNForgot()
2908             throws Exception {
2909         // 1. First request (no user approval bypass)
2910         sendNetworkRequestAndSetupForConnectionStatus();
2911 
2912         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
2913         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2914         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
2915                 mConnectHelper);
2916 
2917         // 2. Simulate user forgeting the network.
2918         when(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(
2919                 ScanResultUtil.createQuotedSsid(mTestScanDatas[0].getResults()[0].SSID)))
2920                 .thenReturn(true);
2921 
2922         // 3. Second request for the same access point (user approval bypass).
2923         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
2924         PatternMatcher ssidPatternMatch =
2925                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2926         Pair<MacAddress, MacAddress> bssidPatternMatch =
2927                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2928                         MacAddress.BROADCAST_ADDRESS);
2929         attachWifiNetworkSpecifierAndAppInfo(
2930                 ssidPatternMatch, bssidPatternMatch,
2931                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
2932                 new int[0]);
2933         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2934         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
2935         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
2936         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2937         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2938                 ArgumentCaptor.forClass(List.class);
2939         // Verify we triggered the match callback.
2940         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2941         assertNotNull(matchedScanResultsCaptor.getValue());
2942         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2943         // Verify that we did not send a connection attempt to ModeImplProxy.
2944         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
2945                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
2946     }
2947 
2948     /**
2949      * Verify that we don't bypass user approval for a specific request for an access point of
2950      * a open network that was not approved previously, even if the network (not access point)
2951      * had been approved.
2952      */
2953     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchNotApprovedForOpenNetwork()2954     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchNotApprovedForOpenNetwork()
2955             throws Exception {
2956         // 1. First request (no user approval bypass)
2957         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1, true);
2958 
2959         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
2960         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
2961         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
2962                 mConnectHelper);
2963 
2964         // 2. Second request for a different access point (but same network).
2965         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
2966                 TEST_SSID_1, TEST_SSID_1, TEST_SSID_3, TEST_SSID_4);
2967         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[1];
2968         PatternMatcher ssidPatternMatch =
2969                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
2970         Pair<MacAddress, MacAddress> bssidPatternMatch =
2971                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
2972                         MacAddress.BROADCAST_ADDRESS);
2973         attachWifiNetworkSpecifierAndAppInfo(
2974                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
2975                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
2976         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
2977         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
2978         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
2979         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
2980         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
2981                 ArgumentCaptor.forClass(List.class);
2982         // Verify we triggered the match callback.
2983         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
2984         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
2985         assertNotNull(matchedScanResultsCaptor.getValue());
2986         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
2987         // Verify that we did not send a connection attempt to ClientModeManager.
2988         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
2989                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
2990     }
2991 
2992     /**
2993      * Verify that we don't bypass user approval for a specific request for a open network
2994      * (not access point) that was approved previously.
2995      */
2996     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchNotApprovedForOpenNetwork()2997     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchNotApprovedForOpenNetwork()
2998             throws Exception {
2999         // 1. First request (no user approval bypass)
3000         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1, true);
3001 
3002         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
3003         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
3004         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
3005                 mConnectHelper);
3006 
3007         // 2. Second request for the same network (but not specific access point)
3008         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3009         PatternMatcher ssidPatternMatch =
3010                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3011         // match-all.
3012         Pair<MacAddress, MacAddress> bssidPatternMatch =
3013                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3014         attachWifiNetworkSpecifierAndAppInfo(
3015                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createOpenNetwork(),
3016                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
3017         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3018         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3019         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3020         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3021         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
3022                 ArgumentCaptor.forClass(List.class);
3023         // Verify we triggered the match callback.
3024         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
3025         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
3026         assertNotNull(matchedScanResultsCaptor.getValue());
3027         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
3028         // Verify that we did not send a connection attempt to ClientModeManager.
3029         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
3030                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3031     }
3032 
3033     /**
3034      * Verify that we bypass user approval for a specific request for a non-open network
3035      * (not access point) that was approved previously.
3036      */
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved( boolean bypassActivated)3037     private void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved(
3038             boolean bypassActivated) throws Exception {
3039         ArgumentCaptor<WifiConfiguration> configurationArgumentCaptor =
3040                 ArgumentCaptor.forClass(WifiConfiguration.class);
3041         // 1. First request (no user approval bypass)
3042         sendNetworkRequestAndSetupForConnectionStatus();
3043 
3044         verify(mWifiConfigManager).addOrUpdateNetwork(
3045                 configurationArgumentCaptor.capture(), anyInt(), anyString(), eq(false));
3046         // BSSID should be non-null when the user selects the network
3047         assertNotNull(configurationArgumentCaptor.getValue().BSSID);
3048 
3049         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
3050         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
3051         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
3052                 mConnectHelper);
3053 
3054         // 2. Second request for the same network (but not specific access point)
3055         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3056         PatternMatcher ssidPatternMatch =
3057                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3058         // match-all.
3059         Pair<MacAddress, MacAddress> bssidPatternMatch =
3060                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3061         attachWifiNetworkSpecifierAndAppInfo(
3062                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
3063                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
3064         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3065 
3066         // Connection does not happen yet since it is waiting for scan results.
3067         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
3068                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3069 
3070         // simulate scan results coming in and verify we auto connect to the network
3071         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3072         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3073         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3074         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
3075                 ArgumentCaptor.forClass(List.class);
3076         // Verify the match callback is not triggered since the UI is not started.
3077         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
3078         verify(mNetworkRequestMatchCallback, bypassActivated ? never() : times(1)).onMatch(
3079                 matchedScanResultsCaptor.capture());
3080 
3081         // Verify we added a WIfiConfiguration with non-null BSSID, and a connection is initiated.
3082         verify(mWifiConfigManager, bypassActivated ? times(2) : times(1)).addOrUpdateNetwork(
3083                 configurationArgumentCaptor.capture(), anyInt(), anyString(), eq(false));
3084         assertNotNull(configurationArgumentCaptor.getAllValues().get(0).BSSID);
3085         if (bypassActivated) {
3086             assertNotNull(configurationArgumentCaptor.getAllValues().get(1).BSSID);
3087             verify(mConnectHelper).connectToNetwork(any(), any(),
3088                     mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3089         }
3090     }
3091 
3092     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApprovedNoStaSta()3093     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApprovedNoStaSta()
3094             throws Exception {
3095         testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved(true);
3096     }
3097 
3098     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApprovedYesStaSta()3099     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApprovedYesStaSta()
3100             throws Exception {
3101         when(mResources.getBoolean(
3102                 eq(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)))
3103                 .thenReturn(true);
3104         testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchApproved(false);
3105     }
3106 
3107     /**
3108      * Verify the we don't bypass user approval for a specific request for an access point that was
3109      * already approved previously, but was then removed (app uninstalled, user deleted it from
3110      * notification, from tests, etc).
3111      */
3112     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterApprovalsRemove()3113     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterApprovalsRemove()
3114             throws Exception {
3115         // 1. First request (no user approval bypass)
3116         sendNetworkRequestAndSetupForConnectionStatus();
3117 
3118         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
3119         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
3120         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
3121                 mConnectHelper);
3122 
3123         // 2. Remove all approvals for the app.
3124         mWifiNetworkFactory.removeApp(TEST_PACKAGE_NAME_1);
3125 
3126         // 3. Second request for the same access point
3127         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3128         PatternMatcher ssidPatternMatch =
3129                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3130         Pair<MacAddress, MacAddress> bssidPatternMatch =
3131                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
3132                         MacAddress.BROADCAST_ADDRESS);
3133         attachWifiNetworkSpecifierAndAppInfo(
3134                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
3135                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
3136         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3137         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3138         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3139         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3140         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
3141                 ArgumentCaptor.forClass(List.class);
3142         // Verify we triggered the match callback.
3143         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
3144         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
3145         assertNotNull(matchedScanResultsCaptor.getValue());
3146         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
3147         // Verify that we did not send a connection attempt to ClientModeManager.
3148         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
3149                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3150     }
3151 
3152     /**
3153      * Verify the we don't bypass user approval for a specific request for an access point that was
3154      * already approved previously, but then the user perform network settings reset.
3155      */
3156     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterClear()3157     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchAfterClear()
3158             throws Exception {
3159         // 1. First request (no user approval bypass)
3160         sendNetworkRequestAndSetupForConnectionStatus();
3161 
3162         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
3163         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
3164         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
3165                 mConnectHelper);
3166 
3167         // 2. Remove all approvals.
3168         mWifiNetworkFactory.clear();
3169 
3170         // 3. Second request for the same access point
3171         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3172         PatternMatcher ssidPatternMatch =
3173                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3174         Pair<MacAddress, MacAddress> bssidPatternMatch =
3175                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
3176                         MacAddress.BROADCAST_ADDRESS);
3177         attachWifiNetworkSpecifierAndAppInfo(
3178                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
3179                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
3180         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3181         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3182         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3183         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3184         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
3185                 ArgumentCaptor.forClass(List.class);
3186         // Verify we triggered the match callback.
3187         matchedScanResultsCaptor = ArgumentCaptor.forClass(List.class);
3188         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
3189         assertNotNull(matchedScanResultsCaptor.getValue());
3190         validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
3191         // Verify that we did not send a connection attempt to ClientModeManager.
3192         verify(mConnectHelper, never()).connectToNetwork(any(), any(),
3193                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3194     }
3195 
3196     /**
3197      * Verify the config store save for store user approval.
3198      */
3199     @Test
testNetworkSpecifierUserApprovalConfigStoreSave()3200     public void testNetworkSpecifierUserApprovalConfigStoreSave()
3201             throws Exception {
3202         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
3203 
3204         // Verify config store interactions.
3205         verify(mWifiConfigManager).saveToStore(true);
3206         assertTrue(mDataSource.hasNewDataToSerialize());
3207 
3208         Map<String, Set<AccessPoint>> approvedAccessPointsMapToWrite = mDataSource.toSerialize();
3209         assertEquals(1, approvedAccessPointsMapToWrite.size());
3210         assertTrue(approvedAccessPointsMapToWrite.keySet().contains(TEST_PACKAGE_NAME_1));
3211         Set<AccessPoint> approvedAccessPointsToWrite =
3212                 approvedAccessPointsMapToWrite.get(TEST_PACKAGE_NAME_1);
3213         Set<AccessPoint> expectedApprovedAccessPoints = Set.of(
3214                 new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
3215                             WifiConfiguration.SECURITY_TYPE_PSK));
3216         assertEquals(expectedApprovedAccessPoints, approvedAccessPointsToWrite);
3217         // Ensure that the new data flag has been reset after read.
3218         assertFalse(mDataSource.hasNewDataToSerialize());
3219     }
3220 
3221     /**
3222      * Verify the config store load for store user approval.
3223      */
3224     @Test
testNetworkSpecifierUserApprovalConfigStoreLoad()3225     public void testNetworkSpecifierUserApprovalConfigStoreLoad()
3226             throws Exception {
3227         Map<String, Set<AccessPoint>> approvedAccessPointsMapToRead = new HashMap<>();
3228         Set<AccessPoint> approvedAccessPoints = Set.of(
3229                 new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
3230                             WifiConfiguration.SECURITY_TYPE_PSK));
3231         approvedAccessPointsMapToRead.put(TEST_PACKAGE_NAME_1, approvedAccessPoints);
3232         mDataSource.fromDeserialized(approvedAccessPointsMapToRead);
3233 
3234         // The new network request should bypass user approval for the same access point.
3235         PatternMatcher ssidPatternMatch =
3236                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3237         Pair<MacAddress, MacAddress> bssidPatternMatch =
3238                 Pair.create(MacAddress.fromString(TEST_BSSID_1),
3239                         MacAddress.BROADCAST_ADDRESS);
3240         attachWifiNetworkSpecifierAndAppInfo(
3241                 ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
3242                 TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
3243         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3244         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3245         // Ensure we triggered a connect without issuing any scans.
3246         verify(mWifiScanner, never()).startScan(any(), any(), any(), any());
3247 
3248         // Verify we did not trigger the match callback.
3249         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
3250         // Verify that we sent a connection attempt to ClientModeManager
3251         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),  any(),
3252                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3253     }
3254 
3255     /**
3256      * Verify the config store save and load could preserve the elements order.
3257      */
3258     @Test
testStoreConfigSaveAndLoadPreserveOrder()3259     public void testStoreConfigSaveAndLoadPreserveOrder() throws Exception {
3260         LinkedHashSet<AccessPoint> approvedApSet = new LinkedHashSet<>();
3261         approvedApSet.add(new AccessPoint(TEST_SSID_1,
3262                 MacAddress.fromString(TEST_BSSID_1), WifiConfiguration.SECURITY_TYPE_PSK));
3263         approvedApSet.add(new AccessPoint(TEST_SSID_2,
3264                 MacAddress.fromString(TEST_BSSID_2), WifiConfiguration.SECURITY_TYPE_PSK));
3265         approvedApSet.add(new AccessPoint(TEST_SSID_3,
3266                 MacAddress.fromString(TEST_BSSID_3), WifiConfiguration.SECURITY_TYPE_PSK));
3267         approvedApSet.add(new AccessPoint(TEST_SSID_4,
3268                 MacAddress.fromString(TEST_BSSID_4), WifiConfiguration.SECURITY_TYPE_PSK));
3269         mWifiNetworkFactory.mUserApprovedAccessPointMap.put(TEST_PACKAGE_NAME_1,
3270                 new LinkedHashSet<>(approvedApSet));
3271         // Save config.
3272         byte[] xmlData = serializeData();
3273         mWifiNetworkFactory.mUserApprovedAccessPointMap.clear();
3274         // Load config.
3275         deserializeData(xmlData);
3276 
3277         LinkedHashSet<AccessPoint> storedApSet = mWifiNetworkFactory
3278                 .mUserApprovedAccessPointMap.get(TEST_PACKAGE_NAME_1);
3279         // Check load config success and order preserved.
3280         assertNotNull(storedApSet);
3281         assertArrayEquals(approvedApSet.toArray(), storedApSet.toArray());
3282     }
3283 
3284     /**
3285      * Verify the user approval bypass for a specific request for an access point that was already
3286      * approved previously and the scan result is present in the cached scan results.
3287      */
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApproved( boolean bypassActivated)3288     private void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApproved(
3289             boolean bypassActivated) throws Exception {
3290         // 1. First request (no user approval bypass)
3291         sendNetworkRequestAndSetupForConnectionStatus();
3292 
3293         mWifiNetworkFactory.removeCallback(mNetworkRequestMatchCallback);
3294         reset(mNetworkRequestMatchCallback, mWifiScanner, mAlarmManager, mClientModeManager,
3295                 mConnectHelper);
3296         mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
3297 
3298         // 2. Second request for the same access point (user approval bypass).
3299         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3300 
3301         PatternMatcher ssidPatternMatch =
3302                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3303         Pair<MacAddress, MacAddress> bssidPatternMatch =
3304                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
3305                         MacAddress.BROADCAST_ADDRESS);
3306         attachWifiNetworkSpecifierAndAppInfo(
3307                 ssidPatternMatch, bssidPatternMatch,
3308                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
3309                 new int[0]);
3310         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3311 
3312         // Verify we did not trigger the UI for the second request.
3313         verify(mContext, times(bypassActivated ? 1 : 2)).startActivityAsUser(any(), any());
3314         // Verify we did not trigger a scan.
3315         verify(mWifiScanner, bypassActivated ? never() : times(1)).startScan(any(), any(), any(),
3316                 any());
3317         // Verify we did not trigger the match callback.
3318         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
3319         // Verify that we sent a connection attempt to ClientModeManager
3320         if (bypassActivated) {
3321             verify(mConnectHelper).connectToNetwork(eq(mClientModeManager), any(),
3322                     mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3323 
3324             verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
3325         }
3326     }
3327 
3328     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNoStaSta()3329     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedNoStaSta()
3330             throws Exception {
3331         testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApproved(true);
3332     }
3333 
3334     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedYesStaSta()3335     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedYesStaSta()
3336             throws Exception {
3337         when(mResources.getBoolean(
3338                 eq(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)))
3339                 .thenReturn(true);
3340         testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApproved(false);
3341     }
3342 
3343     /**
3344      * Verify the user approval bypass for a specific request for an access point that was already
3345      * approved previously via CDM and the scan result is present in the cached scan results.
3346      */
3347     private void
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDM()3348             testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDM()
3349             throws Exception {
3350         // Setup scan data for WPA-PSK networks.
3351         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
3352                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
3353 
3354         // Choose the matching scan result.
3355         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3356 
3357         // Setup CDM approval for the scan result.
3358         when(mCompanionDeviceManager.isDeviceAssociatedForWifiConnection(
3359                 TEST_PACKAGE_NAME_1,
3360                 MacAddress.fromString(matchingScanResult.BSSID),
3361                 UserHandle.getUserHandleForUid(TEST_UID_1))).thenReturn(true);
3362 
3363         PatternMatcher ssidPatternMatch =
3364                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3365         Pair<MacAddress, MacAddress> bssidPatternMatch =
3366                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
3367                         MacAddress.BROADCAST_ADDRESS);
3368         attachWifiNetworkSpecifierAndAppInfo(
3369                 ssidPatternMatch, bssidPatternMatch,
3370                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
3371                 new int[0]);
3372         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3373 
3374         // Verify we did not trigger the UI for the second request.
3375         verify(mContext, never()).startActivityAsUser(any(), any());
3376         // Verify we did not trigger a scan.
3377         verify(mWifiScanner, never()).startScan(any(), any(), any(), any());
3378         // Verify we did not trigger the match callback.
3379         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
3380         // Verify that we sent a connection attempt to ClientModeManager
3381         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),  any(),
3382                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3383 
3384         verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
3385     }
3386 
3387     @Test
3388     public void
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDMNoStaSta()3389             testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDMNoStaSta()
3390             throws Exception {
3391         testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDM();
3392     }
3393 
3394     @Test
3395     public void
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDMYesStaSta()3396             testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDMYesStaSta()
3397             throws Exception {
3398         when(mResources.getBoolean(
3399                 eq(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)))
3400                 .thenReturn(true);
3401         testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDM();
3402     }
3403 
3404     /**
3405      * Verify the user approval bypass for a specific request for an access point that was already
3406      * approved previously via shell command and the scan result is present in the cached scan
3407      * results.
3408      */
3409     @Test
3410     public void
testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaShell()3411             testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaShell()
3412             throws Exception {
3413         // Setup scan data for WPA-PSK networks.
3414         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
3415                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
3416 
3417         // Choose the matching scan result.
3418         ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
3419 
3420         // Setup shell approval for the scan result.
3421         mWifiNetworkFactory.setUserApprovedApp(TEST_PACKAGE_NAME_1, true);
3422 
3423         PatternMatcher ssidPatternMatch =
3424                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3425         Pair<MacAddress, MacAddress> bssidPatternMatch =
3426                 Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
3427                         MacAddress.BROADCAST_ADDRESS);
3428         attachWifiNetworkSpecifierAndAppInfo(
3429                 ssidPatternMatch, bssidPatternMatch,
3430                 WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
3431                 new int[0]);
3432         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3433 
3434         // Verify we did not trigger the UI for the second request.
3435         verify(mContext, never()).startActivityAsUser(any(), any());
3436         // Verify we did not trigger a scan.
3437         verify(mWifiScanner, never()).startScan(any(), any(), any(), any());
3438         // Verify we did not trigger the match callback.
3439         verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
3440         // Verify that we sent a connection attempt to ClientModeManager
3441         verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),  any(),
3442                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3443 
3444         verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
3445     }
3446 
3447     /**
3448      * Verify network specifier matching for a specifier containing a specific SSID match using
3449      * 4 WPA_PSK scan results, each with unique SSID when the UI callback registration is delayed.
3450      */
3451     @Test
testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchCallbackRegistrationDelayed()3452     public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchCallbackRegistrationDelayed()
3453             throws Exception {
3454         // Setup scan data for open networks.
3455         setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
3456                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
3457 
3458         // Setup network specifier for open networks.
3459         PatternMatcher ssidPatternMatch =
3460                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3461         Pair<MacAddress, MacAddress> bssidPatternMatch =
3462                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3463         WifiConfiguration wifiConfiguration = new WifiConfiguration();
3464         wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
3465         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
3466         attachWifiNetworkSpecifierAndAppInfo(
3467                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
3468                 TEST_PACKAGE_NAME_1, new int[0]);
3469         mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
3470 
3471         validateUiStartParams(true);
3472 
3473         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3474 
3475         // Ensure we did not send any match callbacks, until the callback is registered
3476         verify(mNetworkRequestMatchCallback, never()).onMatch(any());
3477 
3478         // Register the callback & ensure we triggered the on match callback.
3479         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3480         ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
3481                 ArgumentCaptor.forClass(List.class);
3482         verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
3483 
3484         assertNotNull(matchedScanResultsCaptor.getValue());
3485         // We only expect 1 network match in this case.
3486         validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
3487 
3488         verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
3489                 matchedScanResultsCaptor.getValue().size());
3490     }
3491 
3492     /**
3493      * Validates a new network request from a normal app for same network which is already connected
3494      * by another request, the connection will be shared with the new request without reconnection.
3495      */
3496     @Test
testShareConnectedNetworkWithoutCarModePriority()3497     public void testShareConnectedNetworkWithoutCarModePriority() throws Exception {
3498         assumeTrue(SdkLevel.isAtLeastS());
3499         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
3500         mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
3501 
3502         // Connect to request 1
3503         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
3504         // Send network connection success indication.
3505         assertNotNull(mSelectedNetwork);
3506         mSelectedNetwork.BSSID = TEST_BSSID_1;
3507         mWifiNetworkFactory.handleConnectionAttemptEnded(
3508                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
3509 
3510         reset(mClientModeManager);
3511         reset(mConnectHelper);
3512         reset(mWifiConnectivityManager);
3513 
3514         // Setup for connected network
3515         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
3516         when(mWifiScanner.getSingleScanResults())
3517                 .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
3518         when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1);
3519         when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(mSelectedNetwork);
3520 
3521         // Setup network specifier for same networks.
3522         PatternMatcher ssidPatternMatch =
3523                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3524         Pair<MacAddress, MacAddress> bssidPatternMatch =
3525                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3526         attachWifiNetworkSpecifierAndAppInfo(
3527                 ssidPatternMatch, bssidPatternMatch, mSelectedNetwork, TEST_UID_2,
3528                 TEST_PACKAGE_NAME_2, new int[0]);
3529         mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
3530 
3531         validateUiStartParams(true);
3532 
3533         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3534         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3535         verify(mNetworkRequestMatchCallback, atLeastOnce()).onUserSelectionCallbackRegistration(
3536                 mNetworkRequestUserSelectionCallback.capture());
3537 
3538         verify(mNetworkRequestMatchCallback, atLeastOnce()).onMatch(anyList());
3539 
3540         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
3541                 mNetworkRequestUserSelectionCallback.getValue();
3542         assertNotNull(networkRequestUserSelectionCallback);
3543 
3544         // Now trigger user selection to one of the network.
3545         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
3546         mLooper.dispatchAll();
3547 
3548         // Verify no reconnection
3549         verify(mWifiConnectivityManager, never()).setSpecificNetworkRequestInProgress(true);
3550         verify(mClientModeManager, never()).disconnect();
3551         verify(mConnectHelper, never()).connectToNetwork(any(), any(), any(), anyInt(), any());
3552 
3553         // Verify the network will be shared with new request.
3554         assertEquals(2, mWifiNetworkFactory
3555                 .getSpecificNetworkRequestUids(mSelectedNetwork, TEST_BSSID_1).size());
3556     }
3557 
3558     /**
3559      * Validates a new network request with Car Mode Priority for same network which is already
3560      * connected by another request, the connection will disconnect and reconnect.
3561      */
3562     @Test
testShareConnectedNetworkWithCarModePriority()3563     public void testShareConnectedNetworkWithCarModePriority() throws Exception {
3564         assumeTrue(SdkLevel.isAtLeastS());
3565         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
3566         mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
3567         when(mWifiPermissionsUtil.checkEnterCarModePrioritized(TEST_UID_2)).thenReturn(true);
3568 
3569         // Connect to request 1
3570         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
3571         // Send network connection success indication.
3572         assertNotNull(mSelectedNetwork);
3573         mSelectedNetwork.BSSID = TEST_BSSID_1;
3574         mWifiNetworkFactory.handleConnectionAttemptEnded(
3575                 WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork, TEST_BSSID_1, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
3576 
3577         reset(mClientModeManager);
3578         reset(mConnectHelper);
3579         reset(mWifiConnectivityManager);
3580 
3581         // Setup for connected network
3582         when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
3583         when(mWifiScanner.getSingleScanResults())
3584                 .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
3585         when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1);
3586         when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(mSelectedNetwork);
3587 
3588         // Setup network specifier for same networks.
3589         PatternMatcher ssidPatternMatch =
3590                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3591         Pair<MacAddress, MacAddress> bssidPatternMatch =
3592                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3593         attachWifiNetworkSpecifierAndAppInfo(
3594                 ssidPatternMatch, bssidPatternMatch, mSelectedNetwork, TEST_UID_2,
3595                 TEST_PACKAGE_NAME_2, new int[0]);
3596         mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
3597 
3598         validateUiStartParams(true);
3599 
3600         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3601         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3602         verify(mNetworkRequestMatchCallback, atLeastOnce()).onUserSelectionCallbackRegistration(
3603                 mNetworkRequestUserSelectionCallback.capture());
3604 
3605         verify(mNetworkRequestMatchCallback, atLeastOnce()).onMatch(anyList());
3606 
3607         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
3608                 mNetworkRequestUserSelectionCallback.getValue();
3609         assertNotNull(networkRequestUserSelectionCallback);
3610 
3611         // Now trigger user selection to one of the network.
3612         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
3613         mLooper.dispatchAll();
3614 
3615         // Verify disconnect and reconnect
3616         verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
3617         verify(mClientModeManager).disconnect();
3618         verify(mConnectHelper).connectToNetwork(any(), any(), any(), anyInt(), any());
3619 
3620         // Verify the network will be only available to car mode app.
3621         assertEquals(1, mWifiNetworkFactory
3622                 .getSpecificNetworkRequestUids(mSelectedNetwork, TEST_BSSID_1).size());
3623     }
3624 
3625     /**
3626      * Validates a new network request with Car Mode Priority for same network which is already
3627      * a saved network, the connection will be on primary STA and the should have the internet
3628      * capabilities
3629      */
3630     @Test
testShareConnectedNetworkWithCarModePriorityAndSavedNetwork()3631     public void testShareConnectedNetworkWithCarModePriorityAndSavedNetwork() throws Exception {
3632         mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
3633         when(mWifiPermissionsUtil.checkEnterCarModePrioritized(TEST_UID_1)).thenReturn(true);
3634 
3635         // Connect to request 1
3636         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
3637 
3638         sendNetworkRequestAndSetupForUserSelection(TEST_SSID_1, false);
3639 
3640         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
3641                 mNetworkRequestUserSelectionCallback.getValue();
3642         assertNotNull(networkRequestUserSelectionCallback);
3643 
3644         // Now trigger user selection to one of the network.
3645         mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
3646         mSelectedNetwork.SSID = "\"" + TEST_SSID_1 + "\"";
3647         mSelectedNetwork.preSharedKey = TEST_WPA_PRESHARED_KEY;
3648         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
3649                 .thenReturn(List.of(mSelectedNetwork));
3650         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
3651         mLooper.dispatchAll();
3652 
3653         verify(mActiveModeWarden, never()).requestLocalOnlyClientModeManager(
3654                 any(), any(), any(), any(), anyBoolean());
3655         verify(mActiveModeWarden, atLeastOnce()).getPrimaryClientModeManager();
3656         if (SdkLevel.isAtLeastS()) {
3657             verify(mPrimaryClientModeManager, atLeastOnce()).getConnectedWifiConfiguration();
3658             verify(mPrimaryClientModeManager, atLeastOnce()).getConnectingWifiConfiguration();
3659             verify(mPrimaryClientModeManager, atLeastOnce()).getConnectingBssid();
3660             verify(mPrimaryClientModeManager, atLeastOnce()).getConnectedBssid();
3661         }
3662 
3663         // Cancel the periodic scan timer.
3664         mInOrder.verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
3665         // Disable connectivity manager
3666         verify(mWifiConnectivityManager, atLeastOnce()).setSpecificNetworkRequestInProgress(true);
3667 
3668         // Increment the number of unique apps.
3669         verify(mWifiMetrics).incrementNetworkRequestApiNumApps();
3670 
3671         verify(mPrimaryClientModeManager, atLeastOnce()).disconnect();
3672         verify(mConnectHelper, atLeastOnce()).connectToNetwork(
3673                 eq(mPrimaryClientModeManager),
3674                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
3675                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3676         verify(mWifiMetrics, atLeastOnce()).incrementNetworkRequestApiNumConnectOnPrimaryIface();
3677 
3678         // Start the connection timeout alarm.
3679         mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
3680                 eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
3681                 mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
3682         assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
3683         assertTrue(mWifiNetworkFactory.shouldHaveInternetCapabilities());
3684     }
3685 
sendNetworkRequestAndSetupForConnectionStatus()3686     private void sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
3687         sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
3688     }
3689 
sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)3690     private void sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)
3691             throws RemoteException {
3692         sendNetworkRequestAndSetupForConnectionStatus(targetSsid, false);
3693     }
3694 
3695     // Helper method to setup the necessary pre-requisite steps for tracking connection status.
sendNetworkRequestAndSetupForConnectionStatus(String targetSsid, boolean isOpenNetwork)3696     private void sendNetworkRequestAndSetupForConnectionStatus(String targetSsid,
3697             boolean isOpenNetwork)
3698             throws RemoteException {
3699         when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
3700 
3701         sendNetworkRequestAndSetupForUserSelection(targetSsid, isOpenNetwork);
3702 
3703         INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
3704                 mNetworkRequestUserSelectionCallback.getValue();
3705         assertNotNull(networkRequestUserSelectionCallback);
3706 
3707         // Now trigger user selection to one of the network.
3708         mSelectedNetwork = isOpenNetwork
3709                 ? WifiConfigurationTestUtil.createOpenNetwork()
3710                 : WifiConfigurationTestUtil.createPskNetwork();
3711         mSelectedNetwork.SSID = "\"" + targetSsid + "\"";
3712         mSelectedNetwork.preSharedKey = TEST_WPA_PRESHARED_KEY;
3713         sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
3714         mLooper.dispatchAll();
3715 
3716         verify(mActiveModeWarden, atLeastOnce()).requestLocalOnlyClientModeManager(
3717                 any(), any(), any(), any(), anyBoolean());
3718         if (SdkLevel.isAtLeastS()) {
3719             verify(mClientModeManager, atLeastOnce()).getConnectedWifiConfiguration();
3720             verify(mClientModeManager, atLeastOnce()).getConnectingWifiConfiguration();
3721             verify(mClientModeManager, atLeastOnce()).getConnectingBssid();
3722             verify(mClientModeManager, atLeastOnce()).getConnectedBssid();
3723         }
3724 
3725         // Cancel the periodic scan timer.
3726         mInOrder.verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
3727         // Disable connectivity manager
3728         if (mClientModeManager.getRole() == ActiveModeManager.ROLE_CLIENT_PRIMARY) {
3729             verify(mWifiConnectivityManager, atLeastOnce())
3730                     .setSpecificNetworkRequestInProgress(true);
3731         }
3732         // Increment the number of unique apps.
3733         verify(mWifiMetrics).incrementNetworkRequestApiNumApps();
3734 
3735         verify(mClientModeManager, atLeastOnce()).disconnect();
3736         verify(mConnectHelper, atLeastOnce()).connectToNetwork(
3737                 eq(mClientModeManager),
3738                 eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
3739                 mConnectListenerArgumentCaptor.capture(), anyInt(), any());
3740         if (mClientModeManager.getRole() == ActiveModeManager.ROLE_CLIENT_PRIMARY) {
3741             verify(mWifiMetrics, atLeastOnce())
3742                     .incrementNetworkRequestApiNumConnectOnPrimaryIface();
3743         } else {
3744             verify(mWifiMetrics, atLeastOnce())
3745                     .incrementNetworkRequestApiNumConnectOnSecondaryIface();
3746         }
3747 
3748         // Start the connection timeout alarm.
3749         mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
3750                 eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
3751                 mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
3752         assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
3753     }
3754 
sendNetworkRequestAndSetupForUserSelection()3755     private void sendNetworkRequestAndSetupForUserSelection() throws RemoteException {
3756         sendNetworkRequestAndSetupForUserSelection(TEST_SSID_1, false);
3757     }
3758 
3759     // Helper method to setup the necessary pre-requisite steps for user selection.
sendNetworkRequestAndSetupForUserSelection(String targetSsid, boolean isOpenNetwork)3760     private void sendNetworkRequestAndSetupForUserSelection(String targetSsid,
3761             boolean isOpenNetwork)
3762             throws RemoteException {
3763         // Setup scan data for WPA-PSK networks.
3764         setupScanData(isOpenNetwork ? SCAN_RESULT_TYPE_OPEN : SCAN_RESULT_TYPE_WPA_PSK,
3765                 TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
3766 
3767         // Setup network specifier for WPA-PSK networks.
3768         PatternMatcher ssidPatternMatch =
3769                 new PatternMatcher(targetSsid, PatternMatcher.PATTERN_LITERAL);
3770         Pair<MacAddress, MacAddress> bssidPatternMatch =
3771                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3772         WifiConfiguration wifiConfiguration = isOpenNetwork
3773                 ? WifiConfigurationTestUtil.createOpenNetwork()
3774                 : WifiConfigurationTestUtil.createPskNetwork();
3775         wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
3776         attachWifiNetworkSpecifierAndAppInfo(
3777                 ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
3778                 TEST_PACKAGE_NAME_1, new int[0]);
3779         mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
3780 
3781         validateUiStartParams(true);
3782 
3783         when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
3784         mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
3785         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
3786                 mNetworkRequestUserSelectionCallback.capture());
3787 
3788         verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
3789 
3790         verify(mNetworkRequestMatchCallback, atLeastOnce()).onMatch(anyList());
3791     }
3792 
verifyPeriodicScans(long...expectedIntervalsInSeconds)3793     private void verifyPeriodicScans(long...expectedIntervalsInSeconds) {
3794         PeriodicScanParams[] periodicScanParams =
3795                 new PeriodicScanParams[expectedIntervalsInSeconds.length];
3796         for (int i = 0; i < expectedIntervalsInSeconds.length; i++) {
3797             periodicScanParams[i] =
3798                     new PeriodicScanParams(expectedIntervalsInSeconds[i], mTestScanDatas);
3799         }
3800         verifyPeriodicScans(0L, periodicScanParams);
3801     }
3802 
3803     private static class PeriodicScanParams {
3804         public final long expectedIntervalInSeconds;
3805         public final WifiScanner.ScanData[] scanDatas;
3806 
PeriodicScanParams(long expectedIntervalInSeconds, WifiScanner.ScanData[] scanDatas)3807         PeriodicScanParams(long expectedIntervalInSeconds, WifiScanner.ScanData[] scanDatas) {
3808             this.expectedIntervalInSeconds = expectedIntervalInSeconds;
3809             this.scanDatas = scanDatas;
3810         }
3811     }
3812 
3813     // Simulates the periodic scans performed to find a matching network.
3814     // a) Start scan
3815     // b) Scan results received.
3816     // c) Set alarm for next scan at the expected interval.
3817     // d) Alarm fires, go to step a) again and repeat.
verifyPeriodicScans(long nowMs, PeriodicScanParams... scanParams)3818     private void verifyPeriodicScans(long nowMs, PeriodicScanParams... scanParams) {
3819         when(mClock.getElapsedSinceBootMillis()).thenReturn(nowMs);
3820 
3821         OnAlarmListener alarmListener = null;
3822         ScanListener scanListener = null;
3823 
3824         mInOrder = inOrder(mWifiScanner, mAlarmManager);
3825 
3826         // Before we start scans, ensure that we look at the latest cached scan results.
3827         mInOrder.verify(mWifiScanner).getSingleScanResults();
3828 
3829         for (int i = 0; i < scanParams.length - 1; i++) {
3830             long expectedCurrentIntervalInMs = scanParams[i].expectedIntervalInSeconds;
3831             long expectedNextIntervalInMs = scanParams[i + 1].expectedIntervalInSeconds;
3832 
3833             // First scan is immediately fired, so need for the alarm to fire.
3834             if (expectedCurrentIntervalInMs != 0) {
3835                 // Fire the alarm and ensure that we started the next scan.
3836                 alarmListener.onAlarm();
3837             }
3838             mInOrder.verify(mWifiScanner).startScan(
3839                     any(), any(), mScanListenerArgumentCaptor.capture(), any());
3840             scanListener = mScanListenerArgumentCaptor.getValue();
3841             assertNotNull(scanListener);
3842 
3843             // Now trigger the scan results callback and verify the alarm set for the next scan.
3844             scanListener.onResults(scanParams[i].scanDatas);
3845 
3846             mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
3847                     eq(expectedNextIntervalInMs + nowMs), any(),
3848                     mPeriodicScanListenerArgumentCaptor.capture(), any());
3849             alarmListener = mPeriodicScanListenerArgumentCaptor.getValue();
3850             assertNotNull(alarmListener);
3851         }
3852 
3853         mInOrder.verifyNoMoreInteractions();
3854     }
3855 
attachDefaultWifiNetworkSpecifierAndAppInfo(int uid, boolean isHidden, int[] channels)3856     private void attachDefaultWifiNetworkSpecifierAndAppInfo(int uid, boolean isHidden,
3857             int[] channels) {
3858         PatternMatcher ssidPatternMatch =
3859                 new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
3860         Pair<MacAddress, MacAddress> bssidPatternMatch =
3861                 Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
3862         WifiConfiguration wifiConfiguration;
3863         if (isHidden) {
3864             wifiConfiguration = WifiConfigurationTestUtil.createPskHiddenNetwork();
3865         } else {
3866             wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork();
3867         }
3868         String packageName = null;
3869         if (uid == TEST_UID_1) {
3870             packageName = TEST_PACKAGE_NAME_1;
3871         } else if (uid == TEST_UID_2) {
3872             packageName = TEST_PACKAGE_NAME_2;
3873         } else {
3874             fail();
3875         }
3876         attachWifiNetworkSpecifierAndAppInfo(ssidPatternMatch, bssidPatternMatch, wifiConfiguration,
3877                 uid, packageName, channels);
3878     }
3879 
attachWifiNetworkSpecifierAndAppInfo( PatternMatcher ssidPatternMatch, Pair<MacAddress, MacAddress> bssidPatternMatch, WifiConfiguration wifiConfiguration, int uid, String packageName, int[] channels)3880     private void attachWifiNetworkSpecifierAndAppInfo(
3881             PatternMatcher ssidPatternMatch, Pair<MacAddress, MacAddress> bssidPatternMatch,
3882             WifiConfiguration wifiConfiguration, int uid, String packageName, int[] channels) {
3883         mNetworkCapabilities.setRequestorUid(uid);
3884         mNetworkCapabilities.setRequestorPackageName(packageName);
3885         mNetworkCapabilities.setNetworkSpecifier(
3886                 new WifiNetworkSpecifier(ssidPatternMatch, bssidPatternMatch,
3887                         ScanResult.UNSPECIFIED, wifiConfiguration, channels));
3888         mNetworkRequest = new NetworkRequest.Builder()
3889                 .setCapabilities(mNetworkCapabilities)
3890                 .build();
3891     }
3892 
3893     private static final int SCAN_RESULT_TYPE_OPEN = 0;
3894     private static final int SCAN_RESULT_TYPE_WPA_PSK = 1;
3895     private static final int SCAN_RESULT_TYPE_WPA_EAP = 2;
3896     private static final int SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION = 3;
3897 
getScanResultCapsForType(int scanResultType)3898     private String getScanResultCapsForType(int scanResultType) {
3899         switch (scanResultType) {
3900             case SCAN_RESULT_TYPE_OPEN:
3901                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
3902                         WifiConfigurationTestUtil.createOpenNetwork());
3903             case SCAN_RESULT_TYPE_WPA_PSK:
3904                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
3905                         WifiConfigurationTestUtil.createPskNetwork());
3906             case SCAN_RESULT_TYPE_WPA_EAP:
3907                 return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
3908                         WifiConfigurationTestUtil.createEapNetwork());
3909             case SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION:
3910                 return WifiConfigurationTestUtil.getScanResultCapsForWpa2Wpa3TransitionNetwork();
3911         }
3912         fail("Invalid scan result type " + scanResultType);
3913         return "";
3914     }
3915 
setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3, String ssid4)3916     private void setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3,
3917             String ssid4) {
3918         setupScanData(mTestScanDatas, scanResultType, ssid1, ssid2, ssid3, ssid4);
3919     }
3920 
3921     // Helper method to setup the scan data for verifying the matching algo.
setupScanData(WifiScanner.ScanData[] testScanDatas, int scanResultType, String ssid1, String ssid2, String ssid3, String ssid4)3922     private void setupScanData(WifiScanner.ScanData[] testScanDatas, int scanResultType,
3923             String ssid1, String ssid2, String ssid3, String ssid4) {
3924         // 4 scan results,
3925         assertEquals(1, testScanDatas.length);
3926         ScanResult[] scanResults = testScanDatas[0].getResults();
3927         assertEquals(4, scanResults.length);
3928 
3929         String caps = getScanResultCapsForType(scanResultType);
3930 
3931         // Scan results have increasing RSSI.
3932         scanResults[0].SSID = ssid1;
3933         scanResults[0].setWifiSsid(WifiSsid.fromUtf8Text(ssid1));
3934         scanResults[0].BSSID = TEST_BSSID_1;
3935         scanResults[0].capabilities = caps;
3936         scanResults[0].level = -45;
3937         scanResults[1].SSID = ssid2;
3938         scanResults[1].setWifiSsid(WifiSsid.fromUtf8Text(ssid2));
3939         scanResults[1].BSSID = TEST_BSSID_2;
3940         scanResults[1].capabilities = caps;
3941         scanResults[1].level = -35;
3942         scanResults[2].SSID = ssid3;
3943         scanResults[2].setWifiSsid(WifiSsid.fromUtf8Text(ssid3));
3944         scanResults[2].BSSID = TEST_BSSID_3;
3945         scanResults[2].capabilities = caps;
3946         scanResults[2].level = -25;
3947         scanResults[3].SSID = ssid4;
3948         scanResults[3].setWifiSsid(WifiSsid.fromUtf8Text(ssid4));
3949         scanResults[3].BSSID = TEST_BSSID_4;
3950         scanResults[3].capabilities = caps;
3951         scanResults[3].level = -15;
3952     }
3953 
validateScanResults( List<ScanResult> actualScanResults, ScanResult...expectedScanResults)3954     private void validateScanResults(
3955             List<ScanResult> actualScanResults, ScanResult...expectedScanResults) {
3956         assertEquals(expectedScanResults.length, actualScanResults.size());
3957         for (int i = 0; i < expectedScanResults.length; i++) {
3958             ScanResult expectedScanResult = expectedScanResults[i];
3959             ScanResult actualScanResult = actualScanResults.stream()
3960                     .filter(x -> x.BSSID.equals(expectedScanResult.BSSID))
3961                     .findFirst()
3962                     .orElse(null);
3963             ScanTestUtil.assertScanResultEquals(expectedScanResult, actualScanResult);
3964         }
3965     }
3966 
validateConnectionRetryAttempts(boolean onTimeout)3967     private void validateConnectionRetryAttempts(boolean onTimeout) {
3968         for (int i = 0; i < WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
3969             if (!onTimeout) {
3970                 // Cancel the existing connection timeout.
3971                 mInOrder.verify(mAlarmManager).cancel(
3972                         mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
3973             }
3974 
3975             // Trigger new connection.
3976             mInOrder.verify(mConnectHelper).connectToNetwork(
3977                     eq(mClientModeManager),
3978                     eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
3979                     mConnectListenerArgumentCaptor.capture(),
3980                     anyInt(), any());
3981 
3982             // Start the new connection timeout alarm.
3983             mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
3984                     eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
3985                     mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
3986             assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
3987         }
3988     }
3989 
validateScanSettings(@ullable String hiddenSsid, int[] channels)3990     private void validateScanSettings(@Nullable String hiddenSsid, int[] channels) {
3991         ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue();
3992         assertNotNull(scanSettings);
3993         assertEquals(WifiScanner.WIFI_BAND_ALL, scanSettings.band);
3994         assertEquals(WifiScanner.SCAN_TYPE_HIGH_ACCURACY, scanSettings.type);
3995         assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, scanSettings.reportEvents);
3996         if (hiddenSsid == null) {
3997             assertEquals(Collections.emptyList(), scanSettings.hiddenNetworks);
3998         } else {
3999             assertNotNull(scanSettings.hiddenNetworks.get(0));
4000             assertEquals(scanSettings.hiddenNetworks.get(0).ssid, addEnclosingQuotes(hiddenSsid));
4001         }
4002         WorkSource workSource = mWorkSourceArgumentCaptor.getValue();
4003         assertNotNull(workSource);
4004         assertEquals(TEST_UID_1, workSource.getUid(0));
4005         assertEquals(scanSettings.channels.length, channels.length);
4006         for (int i = 0; i < channels.length; i++) {
4007             assertEquals(channels[i], scanSettings.channels[i].frequency);
4008         }
4009     }
4010 
4011     class WifiConfigMatcher implements ArgumentMatcher<WifiConfiguration> {
4012         private final WifiConfiguration mConfig;
4013 
WifiConfigMatcher(WifiConfiguration config)4014         WifiConfigMatcher(WifiConfiguration config) {
4015             assertNotNull(config);
4016             mConfig = config;
4017             mConfig.shared = false;
4018         }
4019 
4020         @Override
matches(WifiConfiguration otherConfig)4021         public boolean matches(WifiConfiguration otherConfig) {
4022             if (otherConfig == null) return false;
4023             return mConfig.getProfileKey().equals(otherConfig.getProfileKey());
4024         }
4025     }
4026 
validateUiStartParams(boolean expectedIsReqForSingeNetwork)4027     private void validateUiStartParams(boolean expectedIsReqForSingeNetwork) {
4028         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
4029         verify(mContext, atLeastOnce()).startActivityAsUser(
4030                 intentArgumentCaptor.capture(), eq(UserHandle.getUserHandleForUid(TEST_UID_1)));
4031         Intent intent = intentArgumentCaptor.getValue();
4032         assertNotNull(intent);
4033         assertEquals(intent.getAction(), WifiNetworkFactory.UI_START_INTENT_ACTION);
4034         assertTrue(intent.getCategories().contains(WifiNetworkFactory.UI_START_INTENT_CATEGORY));
4035         assertEquals(intent.getStringExtra(WifiNetworkFactory.UI_START_INTENT_EXTRA_APP_NAME),
4036                 TEST_APP_NAME);
4037         assertEquals(expectedIsReqForSingeNetwork, intent.getBooleanExtra(
4038                 WifiNetworkFactory.UI_START_INTENT_EXTRA_REQUEST_IS_FOR_SINGLE_NETWORK, false));
4039         assertTrue((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0);
4040         assertTrue((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0);
4041     }
4042 
validateConnectParams(String ssid, String bssid)4043     private void validateConnectParams(String ssid, String bssid) {
4044         ArgumentCaptor<WifiConfiguration> wifiConfigurationCaptor =
4045                 ArgumentCaptor.forClass(WifiConfiguration.class);
4046         verify(mWifiConfigManager).addOrUpdateNetwork(wifiConfigurationCaptor.capture(),
4047                 eq(TEST_UID_1), eq(TEST_PACKAGE_NAME_1), eq(false));
4048         WifiConfiguration network =  wifiConfigurationCaptor.getValue();
4049         assertNotNull(network);
4050         WifiConfiguration expectedWifiConfiguration =
4051                 new WifiConfiguration(((WifiNetworkSpecifier) mNetworkRequest.networkCapabilities
4052                         .getNetworkSpecifier()).wifiConfiguration);
4053         expectedWifiConfiguration.SSID = ssid;
4054         expectedWifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
4055         expectedWifiConfiguration.BSSID = bssid;
4056         expectedWifiConfiguration.ephemeral = true;
4057         expectedWifiConfiguration.shared = false;
4058         expectedWifiConfiguration.fromWifiNetworkSpecifier = true;
4059         WifiConfigurationTestUtil.assertConfigurationEqual(expectedWifiConfiguration, network);
4060     }
4061 
4062     /**
4063      * Create a test scan data for target SSID list with specified number and encryption type
4064      * @param scanResultType   network encryption type
4065      * @param nums             Number of results with different BSSIDs for one SSID
4066      * @param ssids            target SSID list
4067      */
setupScanDataSameSsidWithDiffBssid(int scanResultType, int nums, String[] ssids)4068     private void setupScanDataSameSsidWithDiffBssid(int scanResultType, int nums, String[] ssids) {
4069         String baseBssid = "11:34:56:78:90:";
4070         int[] freq = new int[nums * ssids.length];
4071         for (int i = 0; i < nums; i++) {
4072             freq[i] = 2417 + i;
4073         }
4074         mTestScanDatas = ScanTestUtil.createScanDatas(new int[][]{ freq });
4075         assertEquals(1, mTestScanDatas.length);
4076         ScanResult[] scanResults = mTestScanDatas[0].getResults();
4077         assertEquals(nums * ssids.length, scanResults.length);
4078         String caps = getScanResultCapsForType(scanResultType);
4079         for (int i = 0; i < ssids.length; i++) {
4080             for (int j = i * nums; j < (i + 1) * nums; j++) {
4081                 scanResults[j].SSID = ssids[i];
4082                 scanResults[j].setWifiSsid(WifiSsid.fromUtf8Text(ssids[i]));
4083                 scanResults[j].BSSID = baseBssid + Integer.toHexString(16 + j);
4084                 scanResults[j].capabilities = caps;
4085                 scanResults[j].level = -45;
4086             }
4087         }
4088     }
4089 
4090     /**
4091      * Helper function for serializing configuration data to a XML block.
4092      *
4093      * @return byte[] of the XML data
4094      * @throws Exception
4095      */
serializeData()4096     private byte[] serializeData() throws Exception {
4097         final XmlSerializer out = new FastXmlSerializer();
4098         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
4099         out.setOutput(outputStream, StandardCharsets.UTF_8.name());
4100         mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
4101         out.flush();
4102         return outputStream.toByteArray();
4103     }
4104 
4105     /**
4106      * Helper function for parsing configuration data from a XML block.
4107      *
4108      * @param data XML data to parse from
4109      * @throws Exception
4110      */
deserializeData(byte[] data)4111     private void deserializeData(byte[] data) throws Exception {
4112         final XmlPullParser in = Xml.newPullParser();
4113         final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
4114         in.setInput(inputStream, StandardCharsets.UTF_8.name());
4115         mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
4116                 WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
4117                 mock(WifiConfigStoreEncryptionUtil.class));
4118     }
4119 
sendUserSelectionSelect(INetworkRequestUserSelectionCallback callback, WifiConfiguration selectedNetwork)4120     private void sendUserSelectionSelect(INetworkRequestUserSelectionCallback callback,
4121             WifiConfiguration selectedNetwork) throws RemoteException {
4122         WifiConfiguration selectedNetworkinCb = new WifiConfiguration();
4123         // only copy over the ssid
4124         selectedNetworkinCb.SSID = selectedNetwork.SSID;
4125         callback.select(selectedNetworkinCb);
4126     }
4127 
setScreenState(boolean screenOn)4128     private void setScreenState(boolean screenOn) {
4129         BroadcastReceiver broadcastReceiver = mBroadcastReceiverCaptor.getValue();
4130         assertNotNull(broadcastReceiver);
4131         Intent intent = new Intent(screenOn  ? ACTION_SCREEN_ON : ACTION_SCREEN_OFF);
4132         broadcastReceiver.onReceive(mContext, intent);
4133     }
4134 }
4135