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