• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import static android.Manifest.permission.ACCESS_WIFI_STATE;
20 import static android.Manifest.permission.MANAGE_WIFI_COUNTRY_CODE;
21 import static android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS;
22 import static android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS;
23 import static android.net.wifi.WifiAvailableChannel.FILTER_REGULATORY;
24 import static android.net.wifi.WifiAvailableChannel.OP_MODE_STA;
25 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
26 import static android.net.wifi.WifiManager.ACTION_REMOVE_SUGGESTION_DISCONNECT;
27 import static android.net.wifi.WifiManager.COEX_RESTRICTION_SOFTAP;
28 import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_AWARE;
29 import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_DIRECT;
30 import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY;
31 import static android.net.wifi.WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1;
32 import static android.net.wifi.WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE;
33 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
34 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
35 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
36 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
37 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
38 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
39 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
40 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
41 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
42 import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
43 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
44 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
45 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
46 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
47 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
48 import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
49 import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
50 
51 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
52 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY;
53 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
54 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
55 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
56 import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
57 import static com.android.server.wifi.SelfRecovery.REASON_API_CALL;
58 import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
59 import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_VERBOSE_LOGGING_ENABLED;
60 
61 import static com.google.common.truth.Truth.assertThat;
62 
63 import static org.junit.Assert.assertArrayEquals;
64 import static org.junit.Assert.assertEquals;
65 import static org.junit.Assert.assertFalse;
66 import static org.junit.Assert.assertNotNull;
67 import static org.junit.Assert.assertNull;
68 import static org.junit.Assert.assertThrows;
69 import static org.junit.Assert.assertTrue;
70 import static org.junit.Assert.fail;
71 import static org.junit.Assume.assumeTrue;
72 import static org.mockito.AdditionalAnswers.returnsSecondArg;
73 import static org.mockito.AdditionalMatchers.aryEq;
74 import static org.mockito.ArgumentMatchers.anySet;
75 import static org.mockito.ArgumentMatchers.notNull;
76 import static org.mockito.ArgumentMatchers.nullable;
77 import static org.mockito.Matchers.any;
78 import static org.mockito.Matchers.anyString;
79 import static org.mockito.Matchers.eq;
80 import static org.mockito.Mockito.anyBoolean;
81 import static org.mockito.Mockito.anyInt;
82 import static org.mockito.Mockito.argThat;
83 import static org.mockito.Mockito.atLeastOnce;
84 import static org.mockito.Mockito.clearInvocations;
85 import static org.mockito.Mockito.doAnswer;
86 import static org.mockito.Mockito.doNothing;
87 import static org.mockito.Mockito.doReturn;
88 import static org.mockito.Mockito.doThrow;
89 import static org.mockito.Mockito.ignoreStubs;
90 import static org.mockito.Mockito.inOrder;
91 import static org.mockito.Mockito.isNull;
92 import static org.mockito.Mockito.lenient;
93 import static org.mockito.Mockito.mock;
94 import static org.mockito.Mockito.never;
95 import static org.mockito.Mockito.reset;
96 import static org.mockito.Mockito.spy;
97 import static org.mockito.Mockito.times;
98 import static org.mockito.Mockito.validateMockitoUsage;
99 import static org.mockito.Mockito.verify;
100 import static org.mockito.Mockito.verifyNoMoreInteractions;
101 import static org.mockito.Mockito.verifyZeroInteractions;
102 import static org.mockito.Mockito.when;
103 
104 import android.Manifest;
105 import android.app.ActivityManager;
106 import android.app.AppOpsManager;
107 import android.app.admin.DevicePolicyManager;
108 import android.app.admin.WifiSsidPolicy;
109 import android.app.test.MockAnswerUtil.AnswerWithArguments;
110 import android.bluetooth.BluetoothAdapter;
111 import android.content.AttributionSource;
112 import android.content.BroadcastReceiver;
113 import android.content.ContentResolver;
114 import android.content.Context;
115 import android.content.Intent;
116 import android.content.IntentFilter;
117 import android.content.pm.ApplicationInfo;
118 import android.content.pm.PackageInfo;
119 import android.content.pm.PackageManager;
120 import android.content.res.Resources;
121 import android.net.DhcpInfo;
122 import android.net.DhcpOption;
123 import android.net.DhcpResultsParcelable;
124 import android.net.MacAddress;
125 import android.net.NetworkStack;
126 import android.net.Uri;
127 import android.net.wifi.CoexUnsafeChannel;
128 import android.net.wifi.IActionListener;
129 import android.net.wifi.IBooleanListener;
130 import android.net.wifi.ICoexCallback;
131 import android.net.wifi.IDppCallback;
132 import android.net.wifi.IInterfaceCreationInfoCallback;
133 import android.net.wifi.ILastCallerListener;
134 import android.net.wifi.ILocalOnlyHotspotCallback;
135 import android.net.wifi.INetworkRequestMatchCallback;
136 import android.net.wifi.IOnWifiActivityEnergyInfoListener;
137 import android.net.wifi.IOnWifiDriverCountryCodeChangedListener;
138 import android.net.wifi.IOnWifiUsabilityStatsListener;
139 import android.net.wifi.IPnoScanResultsCallback;
140 import android.net.wifi.IScanResultsCallback;
141 import android.net.wifi.ISoftApCallback;
142 import android.net.wifi.ISubsystemRestartCallback;
143 import android.net.wifi.ISuggestionConnectionStatusListener;
144 import android.net.wifi.ISuggestionUserApprovalStatusListener;
145 import android.net.wifi.ITrafficStateCallback;
146 import android.net.wifi.IWifiConnectedNetworkScorer;
147 import android.net.wifi.IWifiVerboseLoggingStatusChangedListener;
148 import android.net.wifi.ScanResult;
149 import android.net.wifi.SecurityParams;
150 import android.net.wifi.SoftApCapability;
151 import android.net.wifi.SoftApConfiguration;
152 import android.net.wifi.SoftApInfo;
153 import android.net.wifi.WifiAvailableChannel;
154 import android.net.wifi.WifiClient;
155 import android.net.wifi.WifiConfiguration;
156 import android.net.wifi.WifiConfiguration.KeyMgmt;
157 import android.net.wifi.WifiContext;
158 import android.net.wifi.WifiEnterpriseConfig;
159 import android.net.wifi.WifiInfo;
160 import android.net.wifi.WifiManager;
161 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
162 import android.net.wifi.WifiNetworkSuggestion;
163 import android.net.wifi.WifiScanner;
164 import android.net.wifi.WifiSsid;
165 import android.net.wifi.hotspot2.IProvisioningCallback;
166 import android.net.wifi.hotspot2.OsuProvider;
167 import android.net.wifi.hotspot2.PasspointConfiguration;
168 import android.net.wifi.hotspot2.pps.Credential;
169 import android.net.wifi.hotspot2.pps.HomeSp;
170 import android.os.Binder;
171 import android.os.Build;
172 import android.os.Bundle;
173 import android.os.Handler;
174 import android.os.HandlerThread;
175 import android.os.IBinder;
176 import android.os.IPowerManager;
177 import android.os.IThermalService;
178 import android.os.Parcel;
179 import android.os.ParcelFileDescriptor;
180 import android.os.PowerManager;
181 import android.os.Process;
182 import android.os.RemoteException;
183 import android.os.UserHandle;
184 import android.os.UserManager;
185 import android.os.WorkSource;
186 import android.os.connectivity.WifiActivityEnergyInfo;
187 import android.os.test.TestLooper;
188 import android.telephony.CarrierConfigManager;
189 import android.telephony.PhoneStateListener;
190 import android.telephony.SubscriptionManager;
191 import android.telephony.TelephonyManager;
192 import android.util.Pair;
193 
194 import androidx.test.filters.SmallTest;
195 
196 import com.android.internal.os.PowerProfile;
197 import com.android.modules.utils.ParceledListSlice;
198 import com.android.modules.utils.build.SdkLevel;
199 import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
200 import com.android.server.wifi.WifiServiceImpl.SoftApCallbackInternal;
201 import com.android.server.wifi.coex.CoexManager;
202 import com.android.server.wifi.hotspot2.PasspointManager;
203 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil;
204 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
205 import com.android.server.wifi.util.ActionListenerWrapper;
206 import com.android.server.wifi.util.ApConfigUtil;
207 import com.android.server.wifi.util.LastCallerInfoManager;
208 import com.android.server.wifi.util.WifiPermissionsUtil;
209 import com.android.server.wifi.util.WifiPermissionsWrapper;
210 import com.android.wifi.resources.R;
211 
212 import com.google.common.base.Strings;
213 
214 import org.junit.After;
215 import org.junit.Before;
216 import org.junit.Test;
217 import org.mockito.ArgumentCaptor;
218 import org.mockito.ArgumentMatcher;
219 import org.mockito.Captor;
220 import org.mockito.InOrder;
221 import org.mockito.Mock;
222 import org.mockito.MockitoAnnotations;
223 import org.mockito.MockitoSession;
224 
225 import java.io.FileDescriptor;
226 import java.io.PrintWriter;
227 import java.io.StringWriter;
228 import java.util.ArrayList;
229 import java.util.Arrays;
230 import java.util.Collections;
231 import java.util.HashMap;
232 import java.util.List;
233 import java.util.Map;
234 
235 /**
236  * Unit tests for {@link WifiServiceImpl}.
237  *
238  * Note: this is intended to build up over time and will not immediately cover the entire file.
239  */
240 @SmallTest
241 public class WifiServiceImplTest extends WifiBaseTest {
242 
243     private static final String TAG = "WifiServiceImplTest";
244     private static final String SCAN_PACKAGE_NAME = "scanPackage";
245     private static final int DEFAULT_VERBOSE_LOGGING = 0;
246     private static final String ANDROID_SYSTEM_PACKAGE = "android";
247     private static final String TEST_PACKAGE_NAME = "TestPackage";
248     private static final String TEST_PACKAGE_NAME_OTHER = "TestPackageOther";
249     private static final String TEST_FEATURE_ID = "TestFeature";
250     private static final String SYSUI_PACKAGE_NAME = "com.android.systemui";
251     private static final int TEST_PID = 6789;
252     private static final int TEST_PID2 = 9876;
253     private static final int TEST_UID = 1200000;
254     private static final int OTHER_TEST_UID = 1300000;
255     private static final int TEST_USER_HANDLE = 13;
256     private static final int TEST_WIFI_CONNECTED_NETWORK_SCORER_IDENTIFIER = 1;
257     private static final String WIFI_IFACE_NAME = "wlan0";
258     private static final String WIFI_IFACE_NAME2 = "wlan1";
259     private static final String TEST_COUNTRY_CODE = "US";
260     private static final String TEST_NEW_COUNTRY_CODE = "TW";
261     private static final String TEST_FACTORY_MAC = "10:22:34:56:78:92";
262     private static final MacAddress TEST_FACTORY_MAC_ADDR = MacAddress.fromString(TEST_FACTORY_MAC);
263     private static final String TEST_FQDN = "testfqdn";
264     private static final String TEST_FRIENDLY_NAME = "testfriendlyname";
265     private static final List<WifiConfiguration> TEST_WIFI_CONFIGURATION_LIST = Arrays.asList(
266             WifiConfigurationTestUtil.generateWifiConfig(
267                     0, 1000000, "\"red\"", true, true, null, null,
268                     SECURITY_NONE),
269             WifiConfigurationTestUtil.generateWifiConfig(
270                     1, 1000001, "\"green\"", true, false, "example.com", "Green",
271                     SECURITY_NONE),
272             WifiConfigurationTestUtil.generateWifiConfig(
273                     2, 1200000, "\"blue\"", false, true, null, null,
274                     SECURITY_NONE),
275             WifiConfigurationTestUtil.generateWifiConfig(
276                     3, 1100000, "\"cyan\"", true, true, null, null,
277                     SECURITY_NONE),
278             WifiConfigurationTestUtil.generateWifiConfig(
279                     4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow",
280                     SECURITY_NONE),
281             WifiConfigurationTestUtil.generateWifiConfig(
282                     5, 1100002, "\"magenta\"", false, false, null, null,
283                     SECURITY_NONE));
284     private static final int TEST_AP_FREQUENCY = 2412;
285     private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
286     private static final int NETWORK_CALLBACK_ID = 1100;
287     private static final String TEST_CAP = "[RSN-PSK-CCMP]";
288     private static final String TEST_SSID = "Sid's Place";
289     private static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
290     private static final String TEST_BSSID = "01:02:03:04:05:06";
291     private static final String TEST_PACKAGE = "package";
292     private static final int TEST_NETWORK_ID = 567;
293     private static final WorkSource TEST_SETTINGS_WORKSOURCE = new WorkSource();
294     private static final int TEST_SUB_ID = 1;
295     private static final byte[] TEST_OUI = new byte[]{0x01, 0x02, 0x03};
296 
297     private SoftApInfo mTestSoftApInfo;
298     private List<SoftApInfo> mTestSoftApInfoList;
299     private Map<String, List<WifiClient>> mTestSoftApClients;
300     private Map<String, SoftApInfo> mTestSoftApInfos;
301     private WifiServiceImpl mWifiServiceImpl;
302     private TestLooper mLooper;
303     private WifiThreadRunner mWifiThreadRunner;
304     private PowerManager mPowerManager;
305     private PhoneStateListener mPhoneStateListener;
306     private int mPid;
307     private int mPid2 = Process.myPid();
308     private OsuProvider mOsuProvider;
309     private SoftApCallbackInternal mStateMachineSoftApCallback;
310     private SoftApCallbackInternal mLohsApCallback;
311     private String mLohsInterfaceName;
312     private ApplicationInfo mApplicationInfo;
313     private List<ClientModeManager> mClientModeManagers;
314     private Bundle mExtras = new Bundle();
315     private Bundle mAttribution = new Bundle();
316     private static final String DPP_URI = "DPP:some_dpp_uri";
317     private static final String DPP_PRODUCT_INFO = "DPP:some_dpp_uri_info";
318 
319     private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
320             ArgumentCaptor.forClass(BroadcastReceiver.class);
321 
322     final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor =
323             ArgumentCaptor.forClass(SoftApModeConfiguration.class);
324 
325     @Mock Bundle mBundle;
326     @Mock WifiContext mContext;
327     @Mock Context mContextAsUser;
328     @Mock WifiInjector mWifiInjector;
329     @Mock WifiCountryCode mWifiCountryCode;
330     @Mock Clock mClock;
331     @Mock WifiTrafficPoller mWifiTrafficPoller;
332     @Mock ConcreteClientModeManager mClientModeManager;
333     @Mock ActiveModeWarden mActiveModeWarden;
334     @Mock HandlerThread mHandlerThread;
335     @Mock Resources mResources;
336     @Mock FrameworkFacade mFrameworkFacade;
337     @Mock WifiLockManager mLockManager;
338     @Mock WifiMulticastLockManager mWifiMulticastLockManager;
339     @Mock WifiLastResortWatchdog mWifiLastResortWatchdog;
340     @Mock WifiBackupRestore mWifiBackupRestore;
341     @Mock SoftApBackupRestore mSoftApBackupRestore;
342     @Mock WifiMetrics mWifiMetrics;
343     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
344     @Mock WifiPermissionsWrapper mWifiPermissionsWrapper;
345     @Mock WifiSettingsStore mSettingsStore;
346     @Mock ContentResolver mContentResolver;
347     @Mock PackageManager mPackageManager;
348     @Mock UserManager mUserManager;
349     @Mock WifiApConfigStore mWifiApConfigStore;
350     @Mock WifiConfiguration mApConfig;
351     @Mock ActivityManager mActivityManager;
352     @Mock AppOpsManager mAppOpsManager;
353     @Mock IBinder mAppBinder;
354     @Mock IBinder mAnotherAppBinder;
355     @Mock LocalOnlyHotspotRequestInfo mRequestInfo;
356     @Mock LocalOnlyHotspotRequestInfo mRequestInfo2;
357     @Mock IProvisioningCallback mProvisioningCallback;
358     @Mock ISoftApCallback mClientSoftApCallback;
359     @Mock ISoftApCallback mAnotherSoftApCallback;
360     @Mock PowerProfile mPowerProfile;
361     @Mock WifiTrafficPoller mWifiTrafficPolller;
362     @Mock ScanRequestProxy mScanRequestProxy;
363     @Mock WakeupController mWakeupController;
364     @Mock ITrafficStateCallback mTrafficStateCallback;
365     @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback;
366     @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
367     @Mock TelephonyManager mTelephonyManager;
368     @Mock CoexManager mCoexManager;
369     @Mock IOnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
370     @Mock WifiConfigManager mWifiConfigManager;
371     @Mock WifiBlocklistMonitor mWifiBlocklistMonitor;
372     @Mock WifiScoreCard mWifiScoreCard;
373     @Mock WifiHealthMonitor mWifiHealthMonitor;
374     @Mock PasspointManager mPasspointManager;
375     @Mock IDppCallback mDppCallback;
376     @Mock ILocalOnlyHotspotCallback mLohsCallback;
377     @Mock ICoexCallback mCoexCallback;
378     @Mock IScanResultsCallback mScanResultsCallback;
379     @Mock ISuggestionConnectionStatusListener mSuggestionConnectionStatusListener;
380     @Mock ISuggestionUserApprovalStatusListener mSuggestionUserApprovalStatusListener;
381     @Mock IOnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener;
382     @Mock ISubsystemRestartCallback mSubsystemRestartCallback;
383     @Mock IWifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
384     @Mock WifiSettingsConfigStore mWifiSettingsConfigStore;
385     @Mock WifiScanAlwaysAvailableSettingsCompatibility mScanAlwaysAvailableSettingsCompatibility;
386     @Mock PackageInfo mPackageInfo;
387     @Mock WifiConnectivityManager mWifiConnectivityManager;
388     @Mock WifiDataStall mWifiDataStall;
389     @Mock WifiNative mWifiNative;
390     @Mock ConnectHelper mConnectHelper;
391     @Mock IActionListener mActionListener;
392     @Mock WifiNetworkFactory mWifiNetworkFactory;
393     @Mock UntrustedWifiNetworkFactory mUntrustedWifiNetworkFactory;
394     @Mock OemWifiNetworkFactory mOemWifiNetworkFactory;
395     @Mock RestrictedWifiNetworkFactory mRestrictedWifiNetworkFactory;
396     @Mock MultiInternetManager mMultiInternetManager;
397     @Mock MultiInternetWifiNetworkFactory mMultiInternetWifiNetworkFactory;
398     @Mock WifiDiagnostics mWifiDiagnostics;
399     @Mock WifiP2pConnection mWifiP2pConnection;
400     @Mock SimRequiredNotifier mSimRequiredNotifier;
401     @Mock WifiGlobals mWifiGlobals;
402     @Mock AdaptiveConnectivityEnabledSettingObserver mAdaptiveConnectivityEnabledSettingObserver;
403     @Mock MakeBeforeBreakManager mMakeBeforeBreakManager;
404     @Mock WifiCarrierInfoManager mWifiCarrierInfoManager;
405     @Mock OpenNetworkNotifier mOpenNetworkNotifier;
406     @Mock WifiNotificationManager mWifiNotificationManager;
407     @Mock SarManager mSarManager;
408     @Mock SelfRecovery mSelfRecovery;
409     @Mock LastCallerInfoManager mLastCallerInfoManager;
410     @Mock BuildProperties mBuildProperties;
411     @Mock LinkProbeManager mLinkProbeManager;
412     @Mock IOnWifiDriverCountryCodeChangedListener mIOnWifiDriverCountryCodeChangedListener;
413     @Mock WifiShellCommand mWifiShellCommand;
414     @Mock DevicePolicyManager mDevicePolicyManager;
415     @Mock HalDeviceManager mHalDeviceManager;
416     @Mock WifiDialogManager mWifiDialogManager;
417     @Mock WifiKeyStore mWifiKeyStore;
418 
419     @Captor ArgumentCaptor<Intent> mIntentCaptor;
420 
421     private MockitoSession mSession;
422 
423     WifiConfiguration mWifiConfig;
424 
425     WifiLog mLog;
426 
setUp()427     @Before public void setUp() throws Exception {
428         MockitoAnnotations.initMocks(this);
429         mSession = mockitoSession()
430                 .mockStatic(SubscriptionManager.class)
431                 .startMocking();
432 
433         mLog = spy(new LogcatLog(TAG));
434         mLooper = new TestLooper();
435         mApplicationInfo = new ApplicationInfo();
436         mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
437         when(mResources.getInteger(
438                 eq(R.integer.config_wifiHardwareSoftapMaxClientCount)))
439                 .thenReturn(10);
440         WifiInjector.sWifiInjector = mWifiInjector;
441         when(mRequestInfo.getPid()).thenReturn(mPid);
442         when(mRequestInfo2.getPid()).thenReturn(mPid2);
443         when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
444         when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode);
445         when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
446         when(mWifiInjector.getWifiNetworkFactory()).thenReturn(mWifiNetworkFactory);
447         when(mWifiInjector.getUntrustedWifiNetworkFactory())
448                 .thenReturn(mUntrustedWifiNetworkFactory);
449         when(mWifiInjector.getOemWifiNetworkFactory()).thenReturn(mOemWifiNetworkFactory);
450         when(mWifiInjector.getRestrictedWifiNetworkFactory())
451                 .thenReturn(mRestrictedWifiNetworkFactory);
452         when(mWifiInjector.getMultiInternetWifiNetworkFactory())
453                 .thenReturn(mMultiInternetWifiNetworkFactory);
454         when(mWifiInjector.getMultiInternetManager()).thenReturn(mMultiInternetManager);
455         when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics);
456         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
457         when(mWifiInjector.getWifiHandlerThread()).thenReturn(mHandlerThread);
458         when(mWifiInjector.getMakeBeforeBreakManager()).thenReturn(mMakeBeforeBreakManager);
459         when(mWifiInjector.getWifiNotificationManager()).thenReturn(mWifiNotificationManager);
460         when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties);
461         when(mWifiInjector.getLinkProbeManager()).thenReturn(mLinkProbeManager);
462         when(mWifiInjector.makeWifiShellCommand(any())).thenReturn(mWifiShellCommand);
463         when(mHandlerThread.getThreadHandler()).thenReturn(new Handler(mLooper.getLooper()));
464         when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
465         when(mContext.getResources()).thenReturn(mResources);
466         when(mContext.getContentResolver()).thenReturn(mContentResolver);
467         when(mContext.getPackageManager()).thenReturn(mPackageManager);
468         when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
469         when(mPackageManager.checkSignatures(anyInt(), anyInt()))
470                 .thenReturn(PackageManager.SIGNATURE_NO_MATCH);
471         when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
472         doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(),
473                 anyBoolean(), any());
474         when(mFrameworkFacade.getSettingsWorkSource(any())).thenReturn(TEST_SETTINGS_WORKSOURCE);
475         when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
476         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
477         IPowerManager powerManagerService = mock(IPowerManager.class);
478         IThermalService thermalService = mock(IThermalService.class);
479         mPowerManager =
480                 new PowerManager(mContext, powerManagerService, thermalService, new Handler());
481         when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE);
482         when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
483         when(mContext.createContextAsUser(eq(UserHandle.CURRENT), anyInt()))
484                 .thenReturn(mContextAsUser);
485         when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
486         when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager);
487         when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager);
488         when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog);
489         when(mWifiInjector.getWifiBackupRestore()).thenReturn(mWifiBackupRestore);
490         when(mWifiInjector.getSoftApBackupRestore()).thenReturn(mSoftApBackupRestore);
491         when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
492         when(mWifiInjector.getWifiTrafficPoller()).thenReturn(mWifiTrafficPoller);
493         when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil);
494         when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
495         when(mWifiInjector.getWifiSettingsStore()).thenReturn(mSettingsStore);
496         when(mWifiInjector.getClock()).thenReturn(mClock);
497         when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy);
498         when(mWifiInjector.getWakeupController()).thenReturn(mWakeupController);
499         when(mWifiInjector.getWifiNetworkSuggestionsManager())
500                 .thenReturn(mWifiNetworkSuggestionsManager);
501         when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager);
502         when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
503         when(mWifiInjector.getCoexManager()).thenReturn(mCoexManager);
504         when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager);
505         when(mWifiInjector.getWifiBlocklistMonitor()).thenReturn(mWifiBlocklistMonitor);
506         when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager);
507         when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mClientModeManager);
508         when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
509         when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard);
510         when(mWifiInjector.getWifiHealthMonitor()).thenReturn(mWifiHealthMonitor);
511 
512         mWifiThreadRunner = new WifiThreadRunner(new Handler(mLooper.getLooper()));
513         mWifiThreadRunner.setTimeoutsAreErrors(true);
514         when(mWifiInjector.getWifiThreadRunner()).thenReturn(mWifiThreadRunner);
515 
516         when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
517         when(mWifiInjector.getWifiScanAlwaysAvailableSettingsCompatibility())
518                 .thenReturn(mScanAlwaysAvailableSettingsCompatibility);
519         when(mWifiInjector.getWifiConnectivityManager()).thenReturn(mWifiConnectivityManager);
520         when(mWifiInjector.getWifiDataStall()).thenReturn(mWifiDataStall);
521         when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative);
522         when(mWifiInjector.getConnectHelper()).thenReturn(mConnectHelper);
523         when(mWifiInjector.getWifiP2pConnection()).thenReturn(mWifiP2pConnection);
524         when(mWifiInjector.getSimRequiredNotifier()).thenReturn(mSimRequiredNotifier);
525         when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
526         when(mWifiInjector.getAdaptiveConnectivityEnabledSettingObserver())
527                 .thenReturn(mAdaptiveConnectivityEnabledSettingObserver);
528         when(mClientModeManager.syncStartSubscriptionProvisioning(anyInt(),
529                 any(OsuProvider.class), any(IProvisioningCallback.class))).thenReturn(true);
530         // Create an OSU provider that can be provisioned via an open OSU AP
531         mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
532         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
533         when(mContext.getAttributionTag()).thenReturn(TEST_FEATURE_ID);
534         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
535                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
536         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
537                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
538         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_STACK),
539                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
540         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
541                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
542         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true);
543         when(mLohsCallback.asBinder()).thenReturn(mock(IBinder.class));
544         when(mWifiSettingsConfigStore.get(eq(WIFI_VERBOSE_LOGGING_ENABLED))).thenReturn(true);
545         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(false);
546         when(mActiveModeWarden.getClientModeManagersInRoles(
547                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
548                 .thenReturn(Collections.emptyList());
549         when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
550                 .thenReturn(true);
551         // Defaulting apps to target SDK level that's prior to T. This is need for to test for
552         // backward compatibility of API changes.
553         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
554                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(true);
555         when(mWifiInjector.getWifiCarrierInfoManager()).thenReturn(mWifiCarrierInfoManager);
556         when(mWifiInjector.getOpenNetworkNotifier()).thenReturn(mOpenNetworkNotifier);
557         when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
558         when(mAnotherSoftApCallback.asBinder()).thenReturn(mAnotherAppBinder);
559         when(mIOnWifiDriverCountryCodeChangedListener.asBinder()).thenReturn(mAppBinder);
560         when(mWifiInjector.getSarManager()).thenReturn(mSarManager);
561         mClientModeManagers = Arrays.asList(mClientModeManager, mock(ClientModeManager.class));
562         when(mActiveModeWarden.getClientModeManagers()).thenReturn(mClientModeManagers);
563         when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery);
564         when(mWifiInjector.getLastCallerInfoManager()).thenReturn(mLastCallerInfoManager);
565         when(mUserManager.getUserRestrictions()).thenReturn(mBundle);
566         when(mContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager);
567         when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager);
568         when(mWifiInjector.getWifiDialogManager()).thenReturn(mWifiDialogManager);
569         when(mWifiInjector.getWifiKeyStore()).thenReturn(mWifiKeyStore);
570 
571         doAnswer(new AnswerWithArguments() {
572             public void answer(Runnable onStoppedListener) throws Throwable {
573                 onStoppedListener.run();
574             }
575         }).when(mMakeBeforeBreakManager).stopAllSecondaryTransientClientModeManagers(any());
576 
577         mWifiServiceImpl = makeWifiServiceImpl();
578         mDppCallback = new IDppCallback() {
579             @Override
580             public void onSuccessConfigReceived(int newNetworkId) throws RemoteException {
581 
582             }
583 
584             @Override
585             public void onSuccess(int status) throws RemoteException {
586 
587             }
588 
589             @Override
590             public void onFailure(int status, String ssid, String channelList, int[] bandList)
591                     throws RemoteException {
592 
593             }
594 
595             @Override
596             public void onProgress(int status) throws RemoteException {
597 
598             }
599 
600             @Override
601             public void onBootstrapUriGenerated(String uri) throws RemoteException {
602 
603             }
604 
605             @Override
606             public IBinder asBinder() {
607                 return null;
608             }
609         };
610 
611         // permission not granted by default
612         doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
613                 eq(Manifest.permission.NETWORK_SETUP_WIZARD), any());
614         mTestSoftApInfo = new SoftApInfo();
615         mTestSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
616         mTestSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
617         mTestSoftApInfo.setApInstanceIdentifier(WIFI_IFACE_NAME);
618         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(new int[0]);
619 
620         mTestSoftApInfoList = new ArrayList<>();
621         mTestSoftApInfoList.add(mTestSoftApInfo);
622 
623         mTestSoftApClients = new HashMap<>();
624         mTestSoftApClients.put(WIFI_IFACE_NAME, new ArrayList<WifiClient>());
625         mTestSoftApInfos = new HashMap<>();
626         mTestSoftApInfos.put(WIFI_IFACE_NAME, mTestSoftApInfo);
627 
628         mWifiConfig = new WifiConfiguration();
629         mWifiConfig.SSID = TEST_SSID;
630         mWifiConfig.networkId = TEST_NETWORK_ID;
631 
632         mWifiThreadRunner.prepareForAutoDispatch();
633         setup24GhzSupported();
634     }
635 
636     /**
637      * Called after each test
638      */
639     @After
cleanup()640     public void cleanup() {
641         validateMockitoUsage();
642         if (mSession != null) {
643             mSession.finishMocking();
644         }
645     }
646 
stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(TestLooper looper)647     private void stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(TestLooper looper) {
648         looper.dispatchAll();
649         looper.stopAutoDispatchAndIgnoreExceptions();
650     }
651 
makeWifiServiceImpl()652     private WifiServiceImpl makeWifiServiceImpl() {
653         WifiServiceImpl wifiServiceImpl =
654                 new WifiServiceImpl(mContext, mWifiInjector);
655         ArgumentCaptor<SoftApCallbackInternal> softApCallbackCaptor =
656                 ArgumentCaptor.forClass(SoftApCallbackInternal.class);
657         verify(mActiveModeWarden, atLeastOnce()).registerSoftApCallback(
658                 softApCallbackCaptor.capture());
659         mStateMachineSoftApCallback = softApCallbackCaptor.getValue();
660         ArgumentCaptor<SoftApCallbackInternal> lohsCallbackCaptor =
661                 ArgumentCaptor.forClass(SoftApCallbackInternal.class);
662         mLohsInterfaceName = WIFI_IFACE_NAME;
663         verify(mActiveModeWarden, atLeastOnce()).registerLohsCallback(
664                 lohsCallbackCaptor.capture());
665         mLohsApCallback = lohsCallbackCaptor.getValue();
666         mLooper.dispatchAll();
667         return wifiServiceImpl;
668     }
669 
makeWifiServiceImplWithMockRunnerWhichTimesOut()670     private WifiServiceImpl makeWifiServiceImplWithMockRunnerWhichTimesOut() {
671         WifiThreadRunner mockRunner = mock(WifiThreadRunner.class);
672         when(mockRunner.call(any(), any())).then(returnsSecondArg());
673         when(mockRunner.call(any(), any(int.class))).then(returnsSecondArg());
674         when(mockRunner.call(any(), any(boolean.class))).then(returnsSecondArg());
675         when(mockRunner.post(any())).thenReturn(false);
676 
677         when(mWifiInjector.getWifiThreadRunner()).thenReturn(mockRunner);
678         // Reset mWifiCountryCode to avoid verify failure in makeWifiServiceImpl.
679         reset(mWifiCountryCode);
680         return makeWifiServiceImpl();
681     }
682 
683     /**
684      * Test that REMOVE_NETWORK returns failure to public API when WifiConfigManager returns
685      * failure.
686      */
687     @Test
testRemoveNetworkFailureAppBelowQSdk()688     public void testRemoveNetworkFailureAppBelowQSdk() {
689         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
690                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME,
691                         TEST_FEATURE_ID, null);
692         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
693                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
694         when(mWifiConfigManager.removeNetwork(anyInt(), anyInt(), anyString())).thenReturn(false);
695 
696         mLooper.startAutoDispatch();
697         boolean succeeded = mWifiServiceImpl.removeNetwork(0, TEST_PACKAGE_NAME);
698         mLooper.stopAutoDispatchAndIgnoreExceptions();
699         assertFalse(succeeded);
700     }
701 
702     /**
703      * Ensure WifiMetrics.dump() is the only dump called when 'dumpsys wifi WifiMetricsProto' is
704      * called. This is required to support simple metrics collection via dumpsys
705      */
706     @Test
testWifiMetricsDump()707     public void testWifiMetricsDump() {
708         mWifiServiceImpl.checkAndStartWifi();
709         mLooper.dispatchAll();
710         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()),
711                 new String[]{mWifiMetrics.PROTO_DUMP_ARG});
712         mLooper.dispatchAll();
713         verify(mWifiMetrics).setNonPersistentMacRandomizationForceEnabled(anyBoolean());
714         verify(mWifiMetrics).setIsScanningAlwaysEnabled(anyBoolean());
715         verify(mWifiMetrics).setVerboseLoggingEnabled(anyBoolean());
716         verify(mWifiMetrics)
717                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
718         verify(mClientModeManager, never())
719                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
720     }
721 
722     /**
723      * Ensure WifiServiceImpl.dump() doesn't throw an NPE when executed with null args
724      */
725     @Test
testDumpNullArgs()726     public void testDumpNullArgs() {
727         mWifiServiceImpl.checkAndStartWifi();
728         mLooper.dispatchAll();
729         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
730         mLooper.dispatchAll();
731         verify(mWifiDiagnostics).captureBugReportData(
732                 WifiDiagnostics.REPORT_REASON_USER_ACTION);
733         verify(mWifiDiagnostics).dump(any(), any(), any());
734     }
735 
736     @Test
testWifiShellCommandIgnoredBeforeBoot()737     public void testWifiShellCommandIgnoredBeforeBoot() {
738         // needed to mock this to call "handleBootCompleted"
739         when(mWifiInjector.getPasspointProvisionerHandlerThread())
740                 .thenReturn(mock(HandlerThread.class));
741 
742         // verify shell command can't be called before boot complete
743         ParcelFileDescriptor mockDescriptor = mock(ParcelFileDescriptor.class);
744         assertEquals(-1, mWifiServiceImpl.handleShellCommand(mockDescriptor,
745                 mockDescriptor, mockDescriptor, new String[0]));
746 
747         // verify shell command can now be called after boot complete
748         mWifiServiceImpl.handleBootCompleted();
749         mLooper.dispatchAll();
750         assertEquals(0, mWifiServiceImpl.handleShellCommand(mockDescriptor,
751                 mockDescriptor, mockDescriptor, new String[0]));
752     }
753 
754     /**
755      * Verify that metrics is incremented correctly for Privileged Apps.
756      */
757     @Test
testSetWifiEnabledMetricsPrivilegedApp()758     public void testSetWifiEnabledMetricsPrivilegedApp() throws Exception {
759         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
760                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
761         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
762         when(mSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
763         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
764 
765         InOrder inorder = inOrder(mWifiMetrics);
766         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
767         mLooper.dispatchAll();
768         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
769         mLooper.dispatchAll();
770         verify(mWifiConnectivityManager).setAutoJoinEnabledExternal(true);
771         inorder.verify(mWifiMetrics).logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
772         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(true));
773         inorder.verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_TOGGLE_WIFI_OFF),
774                 anyInt());
775         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(false));
776         verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_ENABLED), anyInt(),
777                 anyInt(), anyInt(), anyString(), eq(false));
778     }
779 
780     /**
781      * Verify that metrics is incremented correctly for normal Apps targeting pre-Q.
782      */
783     @Test
testSetWifiEnabledMetricsNormalAppBelowQSdk()784     public void testSetWifiEnabledMetricsNormalAppBelowQSdk() throws Exception {
785         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
786                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
787         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
788                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
789         when(mSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
790         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
791 
792         InOrder inorder = inOrder(mWifiMetrics);
793         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
794         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
795         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(false), eq(true));
796         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(false), eq(false));
797     }
798 
799     /**
800      * Verify that metrics is not incremented by apps targeting Q SDK.
801      */
802     @Test
testSetWifiEnabledMetricsNormalAppTargetingQSdkNoIncrement()803     public void testSetWifiEnabledMetricsNormalAppTargetingQSdkNoIncrement() throws Exception {
804         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
805                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
806         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
807                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
808         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
809         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
810 
811         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
812         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
813         verify(mWifiMetrics, never()).incrementNumWifiToggles(anyBoolean(), anyBoolean());
814     }
815 
816     /**
817      * Verify that wifi can be enabled by a caller with NETWORK_SETTINGS permission.
818      */
819     @Test
testSetWifiEnabledSuccessWithNetworkSettingsPermission()820     public void testSetWifiEnabledSuccessWithNetworkSettingsPermission() throws Exception {
821         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
822                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
823         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
824         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
825         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
826         verify(mActiveModeWarden).wifiToggled(
827                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
828     }
829 
830     /**
831      * Verify that wifi can be enabled by a caller with NETWORK_MANAGED_PROVISIONING permission.
832      */
833     @Test
testSetWifiEnabledSuccessWithNetworkManagedProvisioningPermission()834     public void testSetWifiEnabledSuccessWithNetworkManagedProvisioningPermission()
835             throws Exception {
836         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
837                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
838         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
839         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
840         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
841         verify(mActiveModeWarden).wifiToggled(
842                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
843     }
844 
845     /**
846      * Verify that wifi can be enabled by the DO apps targeting Q SDK.
847      */
848     @Test
testSetWifiEnabledSuccessForDOAppsTargetingQSdk()849     public void testSetWifiEnabledSuccessForDOAppsTargetingQSdk() throws Exception {
850         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
851                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
852         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
853                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
854         when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
855                 .thenReturn(true);
856 
857         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
858         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
859         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
860 
861         verify(mActiveModeWarden).wifiToggled(
862                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
863     }
864 
865     /**
866      * Verify that wifi can be enabled by the system apps targeting Q SDK.
867      */
868     @Test
testSetWifiEnabledSuccessForSystemAppsTargetingQSdk()869     public void testSetWifiEnabledSuccessForSystemAppsTargetingQSdk() throws Exception {
870         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
871                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
872         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
873                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
874         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
875 
876         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
877         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
878         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
879 
880         verify(mActiveModeWarden).wifiToggled(
881                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
882     }
883 
884     /**
885      * Verify that wifi can be enabled by the apps targeting pre-Q SDK.
886      */
887     @Test
testSetWifiEnabledSuccessForAppsTargetingBelowQSdk()888     public void testSetWifiEnabledSuccessForAppsTargetingBelowQSdk() throws Exception {
889         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
890                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
891         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
892                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
893 
894         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
895         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
896         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
897 
898         verify(mActiveModeWarden).wifiToggled(
899                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
900     }
901 
902     /**
903      * Verify that wifi cannot be enabled by the apps targeting Q SDK.
904      */
905     @Test
testSetWifiEnabledFailureForAppsTargetingQSdk()906     public void testSetWifiEnabledFailureForAppsTargetingQSdk() throws Exception {
907         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
908                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
909         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
910                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
911 
912         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
913         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
914         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
915 
916         verify(mActiveModeWarden, never()).wifiToggled(any());
917     }
918 
919     /**
920      * Verify a SecurityException is thrown if OPSTR_CHANGE_WIFI_STATE is disabled for the app.
921      */
922     @Test
testSetWifiEnableAppOpsRejected()923     public void testSetWifiEnableAppOpsRejected() throws Exception {
924         doThrow(new SecurityException()).when(mAppOpsManager)
925                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
926         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
927                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
928         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
929         try {
930             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
931             fail();
932         } catch (SecurityException e) {
933 
934         }
935         verify(mActiveModeWarden, never()).wifiToggled(any());
936     }
937 
938     /**
939      * Verify a SecurityException is thrown if OP_CHANGE_WIFI_STATE is set to MODE_IGNORED
940      * for the app.
941      */
942     @Test // No exception expected, but the operation should not be done
testSetWifiEnableAppOpsIgnored()943     public void testSetWifiEnableAppOpsIgnored() throws Exception {
944         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
945                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
946         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
947                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
948         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
949 
950         mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
951         verify(mActiveModeWarden, never()).wifiToggled(any());
952     }
953 
954     /**
955      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
956      * are in airplane mode.
957      */
958     @Test
testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode()959     public void testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode() throws Exception {
960         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
961         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
962         when(mContext.checkPermission(
963                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
964                 .thenReturn(PackageManager.PERMISSION_GRANTED);
965 
966         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
967         verify(mActiveModeWarden).wifiToggled(
968                 eq(new WorkSource(Binder.getCallingUid(), SYSUI_PACKAGE_NAME)));
969     }
970 
971     /**
972      * Verify that a caller without the NETWORK_SETTINGS permission can't enable wifi
973      * if we are in airplane mode.
974      */
975     @Test
testSetWifiEnabledFromAppFailsWhenInAirplaneMode()976     public void testSetWifiEnabledFromAppFailsWhenInAirplaneMode() throws Exception {
977         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
978                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
979         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
980                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
981         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
982         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
983         when(mContext.checkPermission(
984                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
985                 .thenReturn(PackageManager.PERMISSION_DENIED);
986 
987         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
988         verify(mActiveModeWarden, never()).wifiToggled(any());
989     }
990 
991     /**
992      * Verify that a user (NETWORK_SETTINGS) cannot enable wifi if DISALLOW_CHANGE_WIFI_STATE
993      * user restriction is set.
994      */
995     @Test
testSetWifiEnabledFromUserFailsWhenUserRestrictionSet()996     public void testSetWifiEnabledFromUserFailsWhenUserRestrictionSet() throws Exception {
997         assumeTrue(SdkLevel.isAtLeastT());
998         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
999                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1000 
1001         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1002         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1003         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE),
1004                 any())).thenReturn(true);
1005 
1006         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1007         verify(mActiveModeWarden, never()).wifiToggled(any());
1008     }
1009 
1010     /**
1011      * Verify that apps targeting pre-Q SDK cannot enable wifi if DISALLOW_CHANGE_WIFI_STATE
1012      * user restriction is set.
1013      */
1014     @Test
testSetWifiEnabledFromAppTargetingBelowQSdkFailsWhenUserRestrictionSet()1015     public void testSetWifiEnabledFromAppTargetingBelowQSdkFailsWhenUserRestrictionSet()
1016             throws Exception {
1017         assumeTrue(SdkLevel.isAtLeastT());
1018         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1019                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1020         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1021                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
1022 
1023         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1024         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1025         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE),
1026                 any())).thenReturn(true);
1027 
1028         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1029         verify(mActiveModeWarden, never()).wifiToggled(any());
1030     }
1031 
1032     /**
1033      * Verify that wifi can be enabled by the DO apps even when DISALLOW_CHANGE_WIFI_STATE
1034      * user restriction is set.
1035      */
1036     @Test
testSetWifiEnabledSuccessForDOAppsWhenUserRestrictionSet()1037     public void testSetWifiEnabledSuccessForDOAppsWhenUserRestrictionSet() throws Exception {
1038         assumeTrue(SdkLevel.isAtLeastT());
1039         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1040                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1041         when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
1042                 .thenReturn(true);
1043 
1044         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1045         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1046         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CHANGE_WIFI_STATE),
1047                 any())).thenReturn(true);
1048 
1049         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1050         verify(mActiveModeWarden).wifiToggled(
1051                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1052     }
1053 
1054     /**
1055      * Verify that a dialog is shown for third-party apps targeting pre-Q SDK enabling Wi-Fi.
1056      */
1057     @Test
testSetWifiEnabledDialogForThirdPartyAppsTargetingBelowQSdk()1058     public void testSetWifiEnabledDialogForThirdPartyAppsTargetingBelowQSdk() throws Exception {
1059         when(mResources.getBoolean(
1060                 R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi))
1061                 .thenReturn(true);
1062         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1063                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1064         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1065                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
1066         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1067         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1068         ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
1069         when(mPackageManager.getApplicationInfo(any(), anyInt())).thenReturn(applicationInfo);
1070         String appName = "appName";
1071         when(applicationInfo.loadLabel(any())).thenReturn(appName);
1072         String title = "appName wants to enable Wi-Fi.";
1073         String message = "Enable Wi-Fi?";
1074         String positiveButtonText = "Yes";
1075         String negativeButtonText = "No";
1076         when(mResources.getString(R.string.wifi_enable_request_dialog_title, appName))
1077                 .thenReturn(title);
1078         when(mResources.getString(R.string.wifi_enable_request_dialog_message)).thenReturn(message);
1079         when(mResources.getString(R.string.wifi_enable_request_dialog_positive_button))
1080                 .thenReturn(positiveButtonText);
1081         when(mResources.getString(R.string.wifi_enable_request_dialog_negative_button))
1082                 .thenReturn(negativeButtonText);
1083 
1084         // Verify the negative reply does not enable wifi
1085         WifiDialogManager.DialogHandle dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1086         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1087                 .thenReturn(dialogHandle);
1088         ArgumentCaptor<WifiDialogManager.SimpleDialogCallback> callbackCaptor =
1089                 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class);
1090         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1091         verify(mActiveModeWarden, times(0)).wifiToggled(
1092                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1093         mLooper.dispatchAll();
1094         verify(mWifiDialogManager, times(1)).createSimpleDialog(
1095                 eq(title),
1096                 eq(message),
1097                 eq(positiveButtonText),
1098                 eq(negativeButtonText),
1099                 eq(null),
1100                 callbackCaptor.capture(),
1101                 any());
1102         verify(dialogHandle).launchDialog();
1103         callbackCaptor.getValue().onNegativeButtonClicked();
1104         verify(mActiveModeWarden, times(0)).wifiToggled(
1105                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1106 
1107         // Verify the cancel reply does not enable wifi.
1108         dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1109         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1110                 .thenReturn(dialogHandle);
1111         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1112         mLooper.dispatchAll();
1113         verify(mActiveModeWarden, times(0)).wifiToggled(
1114                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1115         callbackCaptor =
1116                 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class);
1117         verify(mWifiDialogManager, times(2)).createSimpleDialog(
1118                 eq(title),
1119                 eq(message),
1120                 eq(positiveButtonText),
1121                 eq(negativeButtonText),
1122                 eq(null),
1123                 callbackCaptor.capture(),
1124                 any());
1125         verify(dialogHandle).launchDialog();
1126         callbackCaptor.getValue().onCancelled();
1127         verify(mActiveModeWarden, times(0)).wifiToggled(
1128                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1129 
1130         // Verify the positive reply will enable wifi.
1131         dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1132         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1133                 .thenReturn(dialogHandle);
1134         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1135         mLooper.dispatchAll();
1136         verify(mActiveModeWarden, times(0)).wifiToggled(
1137                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1138         callbackCaptor =
1139                 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class);
1140         verify(mWifiDialogManager, times(3)).createSimpleDialog(
1141                 eq(title),
1142                 eq(message),
1143                 eq(positiveButtonText),
1144                 eq(negativeButtonText),
1145                 eq(null),
1146                 callbackCaptor.capture(),
1147                 any());
1148         verify(dialogHandle).launchDialog();
1149         callbackCaptor.getValue().onPositiveButtonClicked();
1150         verify(mActiveModeWarden, times(1)).wifiToggled(
1151                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1152 
1153         // Verify disabling wifi works without dialog.
1154         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1155         dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1156         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1157                 .thenReturn(dialogHandle);
1158         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1159         mLooper.dispatchAll();
1160         verify(mActiveModeWarden, times(2)).wifiToggled(
1161                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1162         verify(dialogHandle, never()).launchDialog();
1163 
1164         // Verify wifi becoming enabled will dismiss any outstanding dialogs.
1165         dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1166         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1167                 .thenReturn(dialogHandle);
1168         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1169         mLooper.dispatchAll();
1170         verify(mActiveModeWarden, times(2)).wifiToggled(
1171                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1172         callbackCaptor =
1173                 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class);
1174         verify(mWifiDialogManager, times(4)).createSimpleDialog(
1175                 eq(title),
1176                 eq(message),
1177                 eq(positiveButtonText),
1178                 eq(negativeButtonText),
1179                 eq(null),
1180                 callbackCaptor.capture(),
1181                 any());
1182         verify(dialogHandle).launchDialog();
1183         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
1184         // Enabled by privileged app
1185         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1186         mLooper.dispatchAll();
1187         verify(mActiveModeWarden, times(3)).wifiToggled(
1188                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1189         verify(dialogHandle).dismissDialog();
1190 
1191         // Verify wifi already enabled will not trigger dialog.
1192         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(false);
1193         dialogHandle = mock(WifiDialogManager.DialogHandle.class);
1194         when(mWifiDialogManager.createSimpleDialog(any(), any(), any(), any(), any(), any(), any()))
1195                 .thenReturn(dialogHandle);
1196         when(mActiveModeWarden.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
1197         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1198         mLooper.dispatchAll();
1199         verify(mActiveModeWarden, times(3)).wifiToggled(
1200                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1201         verify(dialogHandle, never()).launchDialog();
1202     }
1203 
1204     /**
1205      * Verify that no dialog is shown for non-third-party apps targeting pre-Q SDK enabling Wi-Fi.
1206      */
1207     @Test
testSetWifiEnabledNoDialogForNonThirdPartyAppsTargetingBelowQSdk()1208     public void testSetWifiEnabledNoDialogForNonThirdPartyAppsTargetingBelowQSdk() {
1209         when(mResources.getBoolean(
1210                 R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi))
1211                 .thenReturn(true);
1212         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1213                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1214         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1215                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
1216         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1217         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1218         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
1219 
1220         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1221         verify(mActiveModeWarden).wifiToggled(
1222                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1223     }
1224 
1225     /**
1226      * Helper to verify registering for state changes.
1227      */
verifyApRegistration()1228     private void verifyApRegistration() {
1229         assertNotNull(mLohsApCallback);
1230     }
1231 
1232     /**
1233      * Helper to emulate local-only hotspot state changes.
1234      *
1235      * Must call verifyApRegistration first.
1236      */
changeLohsState(int apState, int previousState, int error)1237     private void changeLohsState(int apState, int previousState, int error) {
1238         // TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
1239         //        apState, previousState, error, WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
1240         mLohsApCallback.onStateChanged(apState, error);
1241     }
1242 
1243     /**
1244      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
1245      * are in softap mode.
1246      */
1247     @Test
testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled()1248     public void testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled() throws Exception {
1249         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1250         mWifiServiceImpl.checkAndStartWifi();
1251         mLooper.dispatchAll();
1252 
1253         verifyApRegistration();
1254         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1255 
1256         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
1257         when(mContext.checkPermission(
1258                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
1259                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1260         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1261         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
1262         verify(mActiveModeWarden).wifiToggled(
1263                 eq(new WorkSource(Binder.getCallingUid(), SYSUI_PACKAGE_NAME)));
1264     }
1265 
1266     /**
1267      * Verify that a call from an app cannot enable wifi if we are in softap mode.
1268      */
1269     @Test
testSetWifiEnabledFromAppFailsWhenApEnabled()1270     public void testSetWifiEnabledFromAppFailsWhenApEnabled() throws Exception {
1271         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1272                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1273         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1274                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
1275         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1276         mWifiServiceImpl.checkAndStartWifi();
1277         mLooper.dispatchAll();
1278 
1279         verifyApRegistration();
1280         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1281 
1282         when(mContext.checkPermission(
1283                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
1284                 .thenReturn(PackageManager.PERMISSION_DENIED);
1285         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1286         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1287         verify(mSettingsStore, never()).handleWifiToggled(anyBoolean());
1288         verify(mActiveModeWarden, never()).wifiToggled(any());
1289     }
1290 
1291 
1292     /**
1293      * Verify that the CMD_TOGGLE_WIFI message won't be sent if wifi is already on.
1294      */
1295     @Test
testSetWifiEnabledNoToggle()1296     public void testSetWifiEnabledNoToggle() throws Exception {
1297         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(false);
1298         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1299                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1300         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
1301         verify(mActiveModeWarden, never()).wifiToggled(any());
1302     }
1303 
1304     /**
1305      * Verify a SecurityException is thrown if a caller does not have the CHANGE_WIFI_STATE
1306      * permission to toggle wifi.
1307      */
1308     @Test
testSetWifiEnableWithoutChangeWifiStatePermission()1309     public void testSetWifiEnableWithoutChangeWifiStatePermission() throws Exception {
1310         doThrow(new SecurityException()).when(mContext)
1311                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
1312                                                 eq("WifiService"));
1313         try {
1314             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
1315             fail();
1316         } catch (SecurityException e) {
1317         }
1318     }
1319 
1320     /**
1321      * Verify that wifi can be disabled by a caller with NETWORK_SETTINGS permission.
1322      */
1323     @Test
testSetWifiDisabledSuccessWithNetworkSettingsPermission()1324     public void testSetWifiDisabledSuccessWithNetworkSettingsPermission() throws Exception {
1325         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1326                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1327         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1328         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1329         verify(mActiveModeWarden).wifiToggled(
1330                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1331     }
1332 
1333     /**
1334      * Verify that wifi can be disabled by a caller with NETWORK_MANAGED_PROVISIONING permission.
1335      */
1336     @Test
testSetWifiDisabledSuccessWithNetworkManagedProvisioningPermission()1337     public void testSetWifiDisabledSuccessWithNetworkManagedProvisioningPermission()
1338             throws Exception {
1339         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
1340                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1341         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1342         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1343         verify(mActiveModeWarden).wifiToggled(
1344                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1345     }
1346 
1347     /**
1348      * Verify that wifi can be disabled by the PO apps targeting Q SDK.
1349      */
1350     @Test
testSetWifiDisabledSuccessForPOAppsTargetingQSdk()1351     public void testSetWifiDisabledSuccessForPOAppsTargetingQSdk() throws Exception {
1352         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1353                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1354         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1355                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
1356         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
1357                 .thenReturn(true);
1358 
1359         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1360         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1361         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1362 
1363         verify(mActiveModeWarden).wifiToggled(
1364                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1365     }
1366 
1367     /**
1368      * Verify that wifi can be disabled by the system apps targeting Q SDK.
1369      */
1370     @Test
testSetWifiDisabledSuccessForSystemAppsTargetingQSdk()1371     public void testSetWifiDisabledSuccessForSystemAppsTargetingQSdk() throws Exception {
1372         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1373                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1374         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1375                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
1376         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
1377 
1378         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1379         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1380         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1381 
1382         verify(mActiveModeWarden).wifiToggled(
1383                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1384     }
1385 
1386 
1387     /**
1388      * Verify that wifi can be disabled by the apps targeting pre-Q SDK.
1389      */
1390     @Test
testSetWifiDisabledSuccessForAppsTargetingBelowQSdk()1391     public void testSetWifiDisabledSuccessForAppsTargetingBelowQSdk() throws Exception {
1392         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1393                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1394         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1395                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
1396 
1397         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1398         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1399         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1400 
1401         verify(mActiveModeWarden).wifiToggled(
1402                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1403     }
1404 
1405     /**
1406      * Verify that wifi cannot be disabled by the apps targeting Q SDK.
1407      */
1408     @Test
testSetWifiDisabledFailureForAppsTargetingQSdk()1409     public void testSetWifiDisabledFailureForAppsTargetingQSdk() throws Exception {
1410         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
1411                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
1412         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
1413                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
1414 
1415         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
1416         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
1417         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1418 
1419         verify(mActiveModeWarden, never()).wifiToggled(any());
1420     }
1421 
1422     /**
1423      * Verify that CMD_TOGGLE_WIFI message won't be sent if wifi is already off.
1424      */
1425     @Test
testSetWifiDisabledNoToggle()1426     public void testSetWifiDisabledNoToggle() throws Exception {
1427         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1428                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1429         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false);
1430         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
1431         verify(mActiveModeWarden, never()).wifiToggled(any());
1432     }
1433 
1434     /**
1435      * Verify a SecurityException is thrown if a caller does not have the CHANGE_WIFI_STATE
1436      * permission to toggle wifi.
1437      */
1438     @Test
testSetWifiDisabledWithoutChangeWifiStatePermission()1439     public void testSetWifiDisabledWithoutChangeWifiStatePermission() throws Exception {
1440         doThrow(new SecurityException()).when(mContext)
1441                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
1442                         eq("WifiService"));
1443         try {
1444             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false);
1445             fail();
1446         } catch (SecurityException e) { }
1447     }
1448 
1449     /**
1450      * Verify that the restartWifiSubsystem fails w/o the NETWORK_AIRPLANE_MODE permission.
1451      */
testRestartWifiSubsystemWithoutPermission()1452     @Test public void testRestartWifiSubsystemWithoutPermission() {
1453         assumeTrue(SdkLevel.isAtLeastS());
1454         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
1455                 eq(android.Manifest.permission.RESTART_WIFI_SUBSYSTEM), eq("WifiService"));
1456 
1457         try {
1458             mWifiServiceImpl.restartWifiSubsystem();
1459             fail("restartWifiSubsystem should fail w/o the APM permission!");
1460         } catch (SecurityException e) {
1461             // empty clause
1462         }
1463     }
1464 
1465     /**
1466      * Verify that a call to registerSubsystemRestartCallback throws a SecurityException if the
1467      * caller does not have the ACCESS_WIFI_STATE permission.
1468      */
1469     @Test
testRegisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions()1470     public void testRegisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions() {
1471         assumeTrue(SdkLevel.isAtLeastS());
1472         doThrow(new SecurityException()).when(mContext)
1473                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
1474                         eq("WifiService"));
1475         try {
1476             mWifiServiceImpl.registerSubsystemRestartCallback(mSubsystemRestartCallback);
1477             fail("expected SecurityException");
1478         } catch (SecurityException expected) { }
1479     }
1480 
1481     /**
1482      * Verify that a call to unregisterSubsystemRestartCallback throws a SecurityException if the
1483      * caller does not have the ACCESS_WIFI_STATE permission.
1484      */
1485     @Test
testUnregisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions()1486     public void testUnregisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions() {
1487         assumeTrue(SdkLevel.isAtLeastS());
1488         doThrow(new SecurityException()).when(mContext)
1489                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
1490                         eq("WifiService"));
1491         try {
1492             mWifiServiceImpl.unregisterSubsystemRestartCallback(mSubsystemRestartCallback);
1493             fail("expected SecurityException");
1494         } catch (SecurityException expected) { }
1495     }
1496 
1497 
1498     /**
1499      * Test register and unregister subsystem restart callback will go to ActiveModeManager;
1500      */
1501     @Test
testRegisterUnregisterSubsystemRestartCallback()1502     public void testRegisterUnregisterSubsystemRestartCallback() throws Exception {
1503         assumeTrue(SdkLevel.isAtLeastS());
1504         when(mCoexCallback.asBinder()).thenReturn(mAppBinder);
1505         mWifiServiceImpl.registerSubsystemRestartCallback(mSubsystemRestartCallback);
1506         mLooper.dispatchAll();
1507         verify(mActiveModeWarden).registerSubsystemRestartCallback(mSubsystemRestartCallback);
1508         mWifiServiceImpl.unregisterSubsystemRestartCallback(mSubsystemRestartCallback);
1509         mLooper.dispatchAll();
1510         verify(mActiveModeWarden).unregisterSubsystemRestartCallback(mSubsystemRestartCallback);
1511     }
1512 
1513     /**
1514      * Verify that the restartWifiSubsystem succeeds and passes correct parameters.
1515      */
1516     @Test
testRestartWifiSubsystem()1517     public void testRestartWifiSubsystem() {
1518         assumeTrue(SdkLevel.isAtLeastS());
1519         when(mContext.checkPermission(eq(android.Manifest.permission.RESTART_WIFI_SUBSYSTEM),
1520                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1521 
1522         mWifiServiceImpl.restartWifiSubsystem();
1523         mLooper.dispatchAll();
1524         verify(mSelfRecovery).trigger(eq(REASON_API_CALL));
1525         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_RESTART_WIFI_SUB_SYSTEM),
1526                 anyInt());
1527     }
1528 
1529     /**
1530      * Ensure unpermitted callers cannot write the SoftApConfiguration.
1531      */
1532     @Test
testSetWifiApConfigurationNotSavedWithoutPermission()1533     public void testSetWifiApConfigurationNotSavedWithoutPermission() throws Exception {
1534         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
1535         WifiConfiguration apConfig = new WifiConfiguration();
1536         try {
1537             mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME);
1538             fail("Expected SecurityException");
1539         } catch (SecurityException e) { }
1540     }
1541 
1542     /**
1543      * Ensure softap config is written when the caller has the correct permission.
1544      */
1545     @Test
testSetWifiApConfigurationSuccess()1546     public void testSetWifiApConfigurationSuccess() throws Exception {
1547         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1548         WifiConfiguration wifiApConfig = createValidWifiApConfiguration();
1549 
1550         assertTrue(mWifiServiceImpl.setWifiApConfiguration(wifiApConfig, TEST_PACKAGE_NAME));
1551         mLooper.dispatchAll();
1552         verifyCheckChangePermission(TEST_PACKAGE_NAME);
1553         verify(mWifiApConfigStore).setApConfiguration(eq(
1554                 ApConfigUtil.fromWifiConfiguration(wifiApConfig)));
1555     }
1556 
1557     /**
1558      * Ensure that a null config does not overwrite the saved ap config.
1559      */
1560     @Test
testSetWifiApConfigurationNullConfigNotSaved()1561     public void testSetWifiApConfigurationNullConfigNotSaved() throws Exception {
1562         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1563         assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME));
1564         verify(mWifiApConfigStore, never()).setApConfiguration(isNull(SoftApConfiguration.class));
1565     }
1566 
1567     /**
1568      * Ensure that an invalid config does not overwrite the saved ap config.
1569      */
1570     @Test
testSetWifiApConfigurationWithInvalidConfigNotSaved()1571     public void testSetWifiApConfigurationWithInvalidConfigNotSaved() throws Exception {
1572         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1573         assertFalse(mWifiServiceImpl.setWifiApConfiguration(new WifiConfiguration(),
1574                                                             TEST_PACKAGE_NAME));
1575         verify(mWifiApConfigStore, never()).setApConfiguration(any());
1576     }
1577 
1578     /**
1579      * Ensure unpermitted callers cannot write the SoftApConfiguration.
1580      */
1581     @Test
testSetSoftApConfigurationNotSavedWithoutPermission()1582     public void testSetSoftApConfigurationNotSavedWithoutPermission() throws Exception {
1583         SoftApConfiguration apConfig = createValidSoftApConfiguration();
1584         try {
1585             mWifiServiceImpl.setSoftApConfiguration(apConfig, TEST_PACKAGE_NAME);
1586             fail("Expected SecurityException");
1587         } catch (SecurityException e) { }
1588     }
1589 
1590     /**
1591      * Ensure softap config is written when the caller has the correct permission.
1592      */
1593     @Test
testSetSoftApConfigurationSuccessWithSettingPermission()1594     public void testSetSoftApConfigurationSuccessWithSettingPermission() throws Exception {
1595         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
1596         SoftApConfiguration apConfig = createValidSoftApConfiguration();
1597 
1598         assertTrue(mWifiServiceImpl.setSoftApConfiguration(apConfig, TEST_PACKAGE_NAME));
1599         mLooper.dispatchAll();
1600         verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
1601         verify(mActiveModeWarden).updateSoftApConfiguration(apConfig);
1602         verify(mWifiPermissionsUtil).checkNetworkSettingsPermission(anyInt());
1603     }
1604 
1605     /**
1606      * Ensure softap config is written when the caller has the correct permission.
1607      */
1608     @Test
testSetSoftApConfigurationSuccessWithOverridePermission()1609     public void testSetSoftApConfigurationSuccessWithOverridePermission() throws Exception {
1610         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1611         SoftApConfiguration apConfig = createValidSoftApConfiguration();
1612 
1613         assertTrue(mWifiServiceImpl.setSoftApConfiguration(apConfig, TEST_PACKAGE_NAME));
1614         mLooper.dispatchAll();
1615         verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
1616         verify(mActiveModeWarden).updateSoftApConfiguration(apConfig);
1617         verify(mWifiPermissionsUtil).checkConfigOverridePermission(anyInt());
1618     }
1619 
1620     /**
1621      * Ensure that a null config does not overwrite the saved ap config.
1622      */
1623     @Test
testSetSoftApConfigurationNullConfigNotSaved()1624     public void testSetSoftApConfigurationNullConfigNotSaved() throws Exception {
1625         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1626         assertFalse(mWifiServiceImpl.setSoftApConfiguration(null, TEST_PACKAGE_NAME));
1627         verify(mWifiApConfigStore, never()).setApConfiguration(isNull(SoftApConfiguration.class));
1628         verify(mActiveModeWarden, never()).updateSoftApConfiguration(any());
1629         verify(mWifiPermissionsUtil).checkConfigOverridePermission(anyInt());
1630     }
1631 
1632     /**
1633      * Ensure that an invalid config does not overwrite the saved ap config.
1634      */
1635     @Test
testSetSoftApConfigurationWithInvalidConfigNotSaved()1636     public void testSetSoftApConfigurationWithInvalidConfigNotSaved() throws Exception {
1637         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1638         assertFalse(mWifiServiceImpl.setSoftApConfiguration(
1639                 new SoftApConfiguration.Builder().build(), TEST_PACKAGE_NAME));
1640         verify(mWifiApConfigStore, never()).setApConfiguration(any());
1641         verify(mWifiPermissionsUtil).checkConfigOverridePermission(anyInt());
1642     }
1643 
1644     /**
1645      * Ensure unpermitted callers are not able to retrieve the softap config.
1646      */
1647     @Test
testGetSoftApConfigurationNotReturnedWithoutPermission()1648     public void testGetSoftApConfigurationNotReturnedWithoutPermission() throws Exception {
1649         try {
1650             mWifiServiceImpl.getSoftApConfiguration();
1651             fail("Expected a SecurityException");
1652         } catch (SecurityException e) {
1653         }
1654     }
1655 
1656     /**
1657      * Ensure permitted callers are able to retrieve the softap config.
1658      */
1659     @Test
testGetSoftApConfigurationSuccess()1660     public void testGetSoftApConfigurationSuccess() throws Exception {
1661         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1662         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1663         SoftApConfiguration apConfig = createValidSoftApConfiguration();
1664         when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig);
1665 
1666         mLooper.startAutoDispatch();
1667         assertThat(apConfig).isEqualTo(mWifiServiceImpl.getSoftApConfiguration());
1668 
1669         mLooper.stopAutoDispatchAndIgnoreExceptions();
1670     }
1671 
1672     /**
1673      * Ensure unpermitted callers are not able to retrieve the softap config.
1674      */
1675     @Test
testGetWifiApConfigurationNotReturnedWithoutPermission()1676     public void testGetWifiApConfigurationNotReturnedWithoutPermission() throws Exception {
1677         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
1678         try {
1679             mWifiServiceImpl.getWifiApConfiguration();
1680             fail("Expected a SecurityException");
1681         } catch (SecurityException e) {
1682         }
1683     }
1684 
1685     /**
1686      * Ensure permitted callers are able to retrieve the softap config.
1687      */
1688     @Test
testGetWifiApConfigurationSuccess()1689     public void testGetWifiApConfigurationSuccess() throws Exception {
1690         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1691         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
1692         SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
1693         when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig);
1694 
1695         mLooper.startAutoDispatch();
1696         WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
1697                 apConfig.toWifiConfiguration(),
1698                 mWifiServiceImpl.getWifiApConfiguration());
1699 
1700         mLooper.stopAutoDispatchAndIgnoreExceptions();
1701     }
1702 
1703     /**
1704      * Ensure we return the proper variable for the softap state after getting an AP state change
1705      * broadcast.
1706      */
1707     @Test
testGetWifiApEnabled()1708     public void testGetWifiApEnabled() throws Exception {
1709         // ap should be disabled when wifi hasn't been started
1710         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
1711 
1712         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1713         mWifiServiceImpl.checkAndStartWifi();
1714         mLooper.dispatchAll();
1715 
1716         // ap should be disabled initially
1717         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
1718 
1719         // send an ap state change to verify WifiServiceImpl is updated
1720         verifyApRegistration();
1721         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1722         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
1723         mLooper.dispatchAll();
1724 
1725         assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState());
1726     }
1727 
1728     /**
1729      * Ensure we do not allow unpermitted callers to get the wifi ap state.
1730      */
1731     @Test
testGetWifiApEnabledPermissionDenied()1732     public void testGetWifiApEnabledPermissionDenied() {
1733         // we should not be able to get the state
1734         doThrow(new SecurityException()).when(mContext)
1735                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
1736                                                 eq("WifiService"));
1737 
1738         try {
1739             mWifiServiceImpl.getWifiApEnabledState();
1740             fail("expected SecurityException");
1741         } catch (SecurityException expected) { }
1742     }
1743 
1744     /**
1745      * Make sure we do start WifiController (wifi disabled) if the device is already decrypted.
1746      */
1747     @Test
testWifiControllerStartsWhenDeviceBootsWithWifiDisabled()1748     public void testWifiControllerStartsWhenDeviceBootsWithWifiDisabled() {
1749         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1750         mWifiServiceImpl.checkAndStartWifi();
1751         mLooper.dispatchAll();
1752         verify(mWifiConfigManager).loadFromStore();
1753         verify(mActiveModeWarden).start();
1754         verify(mActiveModeWarden, never()).wifiToggled(any());
1755     }
1756 
1757     @Test
testWifiVerboseLoggingInitialization()1758     public void testWifiVerboseLoggingInitialization() {
1759         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1760         when(mWifiSettingsConfigStore.get(eq(WIFI_VERBOSE_LOGGING_ENABLED))).thenReturn(true);
1761         mWifiServiceImpl.checkAndStartWifi();
1762         mLooper.dispatchAll();
1763         verify(mWifiConfigManager).loadFromStore();
1764         verify(mActiveModeWarden).enableVerboseLogging(true);
1765         // show key mode is always disabled at the beginning.
1766         verify(mWifiGlobals).setShowKeyVerboseLoggingModeEnabled(eq(false));
1767         verify(mActiveModeWarden).start();
1768     }
1769 
1770     /**
1771      * Make sure we do start WifiController (wifi enabled) if the device is already decrypted.
1772      */
1773     @Test
testWifiFullyStartsWhenDeviceBootsWithWifiEnabled()1774     public void testWifiFullyStartsWhenDeviceBootsWithWifiEnabled() {
1775         when(mSettingsStore.handleWifiToggled(true)).thenReturn(true);
1776         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
1777         when(mActiveModeWarden.getWifiState()).thenReturn(WIFI_STATE_DISABLED);
1778         when(mContext.getPackageName()).thenReturn(ANDROID_SYSTEM_PACKAGE);
1779         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1780                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1781         mWifiServiceImpl.checkAndStartWifi();
1782         mLooper.dispatchAll();
1783         verify(mWifiConfigManager).loadFromStore();
1784         verify(mActiveModeWarden).start();
1785     }
1786 
1787     /**
1788      * Verify that the setCoexUnsafeChannels calls the corresponding CoexManager API if
1789      * the config_wifiDefaultCoexAlgorithmEnabled is false.
1790      */
1791     @Test
testSetCoexUnsafeChannelsDefaultAlgorithmDisabled()1792     public void testSetCoexUnsafeChannelsDefaultAlgorithmDisabled() {
1793         assumeTrue(SdkLevel.isAtLeastS());
1794         when(mResources.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
1795                 .thenReturn(false);
1796         List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
1797         unsafeChannels.addAll(Arrays.asList(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6),
1798                 new CoexUnsafeChannel(WIFI_BAND_5_GHZ, 36)));
1799         int coexRestrictions = COEX_RESTRICTION_SOFTAP
1800                 & COEX_RESTRICTION_WIFI_AWARE & COEX_RESTRICTION_WIFI_DIRECT;
1801         mWifiServiceImpl.setCoexUnsafeChannels(unsafeChannels, coexRestrictions);
1802         mLooper.dispatchAll();
1803         verify(mCoexManager, times(1)).setCoexUnsafeChannels(any(), anyInt());
1804     }
1805 
1806     /**
1807      * Verify that the setCoexUnsafeChannels does not call the corresponding CoexManager API if
1808      * the config_wifiDefaultCoexAlgorithmEnabled is true.
1809      */
1810     @Test
testSetCoexUnsafeChannelsDefaultAlgorithmEnabled()1811     public void testSetCoexUnsafeChannelsDefaultAlgorithmEnabled() {
1812         assumeTrue(SdkLevel.isAtLeastS());
1813         when(mResources.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
1814                 .thenReturn(true);
1815         List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
1816         unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6));
1817         unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_5_GHZ, 36));
1818         int coexRestrictions = COEX_RESTRICTION_SOFTAP
1819                 & COEX_RESTRICTION_WIFI_AWARE & COEX_RESTRICTION_WIFI_DIRECT;
1820         mWifiServiceImpl.setCoexUnsafeChannels(unsafeChannels, coexRestrictions);
1821         mLooper.dispatchAll();
1822         verify(mCoexManager, never()).setCoexUnsafeChannels(any(), anyInt());
1823     }
1824 
1825     /**
1826      * Verify that setCoexUnsafeChannels throws an IllegalArgumentException if passed a null set.
1827      */
1828     @Test
testSetCoexUnsafeChannelsNullSet()1829     public void testSetCoexUnsafeChannelsNullSet() {
1830         assumeTrue(SdkLevel.isAtLeastS());
1831         try {
1832             mWifiServiceImpl.setCoexUnsafeChannels(null, 0);
1833             fail("Expected IllegalArgumentException");
1834         } catch (IllegalArgumentException e) {
1835         }
1836     }
1837 
1838     /**
1839      * Test register and unregister callback will go to CoexManager;
1840      */
1841     @Test
testRegisterUnregisterCoexCallback()1842     public void testRegisterUnregisterCoexCallback() throws Exception {
1843         assumeTrue(SdkLevel.isAtLeastS());
1844         when(mCoexCallback.asBinder()).thenReturn(mAppBinder);
1845         mWifiServiceImpl.registerCoexCallback(mCoexCallback);
1846         mLooper.dispatchAll();
1847         verify(mCoexManager).registerRemoteCoexCallback(mCoexCallback);
1848         mWifiServiceImpl.unregisterCoexCallback(mCoexCallback);
1849         mLooper.dispatchAll();
1850         verify(mCoexManager).unregisterRemoteCoexCallback(mCoexCallback);
1851     }
1852 
1853     /**
1854      * Verify that a call to setCoexUnsafeChannels throws a SecurityException if the caller does
1855      * not have the WIFI_UPDATE_COEX_UNSAFE_CHANNELS permission.
1856      */
1857     @Test
testSetCoexUnsafeChannelsThrowsSecurityExceptionOnMissingPermissions()1858     public void testSetCoexUnsafeChannelsThrowsSecurityExceptionOnMissingPermissions() {
1859         assumeTrue(SdkLevel.isAtLeastS());
1860         doThrow(new SecurityException()).when(mContext)
1861                 .enforceCallingOrSelfPermission(eq(WIFI_UPDATE_COEX_UNSAFE_CHANNELS),
1862                         eq("WifiService"));
1863         try {
1864             mWifiServiceImpl.setCoexUnsafeChannels(new ArrayList<>(), 0);
1865             fail("expected SecurityException");
1866         } catch (SecurityException expected) { }
1867     }
1868 
1869     /**
1870      * Verify that a call to registerCoexCallback throws a SecurityException if the caller does
1871      * not have the WIFI_ACCESS_COEX_UNSAFE_CHANNELS permission.
1872      */
1873     @Test
testRegisterCoexCallbackThrowsSecurityExceptionOnMissingPermissions()1874     public void testRegisterCoexCallbackThrowsSecurityExceptionOnMissingPermissions() {
1875         assumeTrue(SdkLevel.isAtLeastS());
1876         doThrow(new SecurityException()).when(mContext)
1877                 .enforceCallingOrSelfPermission(eq(WIFI_ACCESS_COEX_UNSAFE_CHANNELS),
1878                         eq("WifiService"));
1879         try {
1880             mWifiServiceImpl.registerCoexCallback(mCoexCallback);
1881             fail("expected SecurityException");
1882         } catch (SecurityException expected) { }
1883     }
1884 
1885     /**
1886      * Verify that a call to unregisterCoexCallback throws a SecurityException if the caller does
1887      * not have the WIFI_ACCESS_COEX_UNSAFE_CHANNELS permission.
1888      */
1889     @Test
testUnregisterCoexCallbackThrowsSecurityExceptionOnMissingPermissions()1890     public void testUnregisterCoexCallbackThrowsSecurityExceptionOnMissingPermissions() {
1891         assumeTrue(SdkLevel.isAtLeastS());
1892         doThrow(new SecurityException()).when(mContext)
1893                 .enforceCallingOrSelfPermission(eq(WIFI_ACCESS_COEX_UNSAFE_CHANNELS),
1894                         eq("WifiService"));
1895         try {
1896             mWifiServiceImpl.unregisterCoexCallback(mCoexCallback);
1897             fail("expected SecurityException");
1898         } catch (SecurityException expected) { }
1899     }
1900 
1901     /**
1902      * Verify caller with proper permission can call startSoftAp.
1903      */
1904     @Test
testStartSoftApWithPermissionsAndNullConfig()1905     public void testStartSoftApWithPermissionsAndNullConfig() {
1906         mLooper.startAutoDispatch();
1907         boolean result = mWifiServiceImpl.startSoftAp(null, TEST_PACKAGE_NAME);
1908         mLooper.stopAutoDispatchAndIgnoreExceptions();
1909         assertTrue(result);
1910         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
1911                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1912         assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
1913     }
1914 
1915     /**
1916      * Verify caller with proper permissions but an invalid config does not start softap.
1917      */
1918     @Test
testStartSoftApWithPermissionsAndInvalidConfig()1919     public void testStartSoftApWithPermissionsAndInvalidConfig() {
1920         mLooper.startAutoDispatch();
1921         boolean result = mWifiServiceImpl.startSoftAp(mApConfig, TEST_PACKAGE_NAME);
1922         mLooper.stopAutoDispatchAndIgnoreExceptions();
1923         assertFalse(result);
1924         verify(mActiveModeWarden, never()).startSoftAp(any(),
1925                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1926     }
1927 
1928     /**
1929      * Verify caller with proper permission and valid config does start softap.
1930      */
1931     @Test
testStartSoftApWithPermissionsAndValidConfig()1932     public void testStartSoftApWithPermissionsAndValidConfig() {
1933         WifiConfiguration config = createValidWifiApConfiguration();
1934         mLooper.startAutoDispatch();
1935         boolean result = mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME);
1936         mLooper.stopAutoDispatchAndIgnoreExceptions();
1937         assertTrue(result);
1938         verify(mActiveModeWarden).startSoftAp(
1939                 mSoftApModeConfigCaptor.capture(),
1940                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1941         WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
1942                 config,
1943                 mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
1944         verify(mLastCallerInfoManager).put(eq(WifiManager.API_SOFT_AP), anyInt(),
1945                 anyInt(), anyInt(), anyString(), eq(true));
1946     }
1947 
1948     /**
1949      * Verify a SecurityException is thrown when a caller without the correct permission attempts to
1950      * start softap.
1951      */
1952     @Test(expected = SecurityException.class)
testStartSoftApWithoutPermissionThrowsException()1953     public void testStartSoftApWithoutPermissionThrowsException() throws Exception {
1954         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
1955                 .thenReturn(PackageManager.PERMISSION_DENIED);
1956         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
1957                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
1958         mLooper.startAutoDispatch();
1959         mWifiServiceImpl.startSoftAp(null, TEST_PACKAGE_NAME);
1960         mLooper.stopAutoDispatchAndIgnoreExceptions();
1961     }
1962 
1963     /**
1964      * Verify that startSoftAP() succeeds if the caller does not have the NETWORK_STACK permission
1965      * but does have the MAINLINE_NETWORK_STACK permission.
1966      */
1967     @Test
testStartSoftApWithoutNetworkStackWithMainlineNetworkStackSucceeds()1968     public void testStartSoftApWithoutNetworkStackWithMainlineNetworkStackSucceeds() {
1969         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
1970                 .thenReturn(PackageManager.PERMISSION_DENIED);
1971         WifiConfiguration config = createValidWifiApConfiguration();
1972         mLooper.startAutoDispatch();
1973         boolean result = mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME);
1974         mLooper.stopAutoDispatchAndIgnoreExceptions();
1975         assertTrue(result);
1976         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
1977                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
1978         WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
1979                 config,
1980                 mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
1981         verify(mContext).enforceCallingOrSelfPermission(
1982                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
1983     }
1984 
1985     /**
1986      * Verify that startSoftAp() with valid config succeeds after a failed call
1987      */
1988     @Test
testStartSoftApWithValidConfigSucceedsAfterFailure()1989     public void testStartSoftApWithValidConfigSucceedsAfterFailure() {
1990         // First initiate a failed call
1991         mLooper.startAutoDispatch();
1992         assertFalse(mWifiServiceImpl.startSoftAp(mApConfig, TEST_PACKAGE_NAME));
1993         mLooper.stopAutoDispatchAndIgnoreExceptions();
1994         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
1995 
1996         // Next attempt a valid config
1997         WifiConfiguration config = createValidWifiApConfiguration();
1998         mLooper.startAutoDispatch();
1999         assertTrue(mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME));
2000         mLooper.stopAutoDispatchAndIgnoreExceptions();
2001         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2002                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2003         WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
2004                 config,
2005                 mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
2006     }
2007 
2008     /**
2009      * Verify caller with proper permission can call startTetheredHotspot.
2010      */
2011     @Test
testStartTetheredHotspotWithPermissionsAndNullConfig()2012     public void testStartTetheredHotspotWithPermissionsAndNullConfig() {
2013         mLooper.startAutoDispatch();
2014         boolean result = mWifiServiceImpl.startTetheredHotspot(null, TEST_PACKAGE_NAME);
2015         mLooper.stopAutoDispatchAndIgnoreExceptions();
2016         assertTrue(result);
2017         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2018                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2019         assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2020         verify(mLastCallerInfoManager).put(eq(WifiManager.API_TETHERED_HOTSPOT), anyInt(),
2021                 anyInt(), anyInt(), anyString(), eq(true));
2022     }
2023 
2024     /**
2025      * Verify caller with proper permissions but an invalid config does not start softap.
2026      */
2027     @Test
testStartTetheredHotspotWithPermissionsAndInvalidConfig()2028     public void testStartTetheredHotspotWithPermissionsAndInvalidConfig() {
2029         mLooper.startAutoDispatch();
2030         boolean result = mWifiServiceImpl.startTetheredHotspot(
2031                 new SoftApConfiguration.Builder().build(), TEST_PACKAGE_NAME);
2032         mLooper.stopAutoDispatchAndIgnoreExceptions();
2033         assertFalse(result);
2034         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2035     }
2036 
2037     /**
2038      * Verify caller with proper permission and valid config does start softap.
2039      */
2040     @Test
testStartTetheredHotspotWithPermissionsAndValidConfig()2041     public void testStartTetheredHotspotWithPermissionsAndValidConfig() {
2042         SoftApConfiguration config = createValidSoftApConfiguration();
2043         mLooper.startAutoDispatch();
2044         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2045         mLooper.stopAutoDispatchAndIgnoreExceptions();
2046         assertTrue(result);
2047         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2048                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2049         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2050     }
2051 
2052     /**
2053      * Verify that while the DISALLOW_WIFI_TETHERING user restriction is set, softap does not start.
2054      */
2055     @Test
testStartTetheredHotspotWithUserRestriction()2056     public void testStartTetheredHotspotWithUserRestriction() {
2057         assumeTrue(SdkLevel.isAtLeastT());
2058         when(mBundle.getBoolean(UserManager.DISALLOW_WIFI_TETHERING)).thenReturn(true);
2059         mWifiServiceImpl.checkAndStartWifi();
2060         mLooper.dispatchAll();
2061         SoftApConfiguration config = createValidSoftApConfiguration();
2062         mLooper.startAutoDispatch();
2063         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2064         mLooper.stopAutoDispatchAndIgnoreExceptions();
2065         assertFalse(result);
2066         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2067     }
2068 
2069     /**
2070      * Verify that when the DISALLOW_WIFI_TETHERING user restriction is set, softap stops.
2071      */
2072     @Test
testTetheredHotspotDisabledWhenUserRestrictionSet()2073     public void testTetheredHotspotDisabledWhenUserRestrictionSet() {
2074         assumeTrue(SdkLevel.isAtLeastT());
2075         when(mBundle.getBoolean(UserManager.DISALLOW_WIFI_TETHERING)).thenReturn(true);
2076         mLooper.startAutoDispatch();
2077         mWifiServiceImpl.onUserRestrictionsChanged();
2078         mLooper.stopAutoDispatchAndIgnoreExceptions();
2079         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED);
2080     }
2081 
2082     /**
2083      * Verify isWifiBandSupported for 24GHz with an overlay override config
2084      */
2085     @Test
testIsWifiBandSupported24gWithOverride()2086     public void testIsWifiBandSupported24gWithOverride() throws Exception {
2087         when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
2088         mLooper.startAutoDispatch();
2089         assertTrue(mWifiServiceImpl.is24GHzBandSupported());
2090         mLooper.stopAutoDispatchAndIgnoreExceptions();
2091         verify(mWifiNative, never()).getChannelsForBand(anyInt());
2092     }
2093 
2094     /**
2095      * Verify isWifiBandSupported for 5GHz with an overlay override config
2096      */
2097     @Test
testIsWifiBandSupported5gWithOverride()2098     public void testIsWifiBandSupported5gWithOverride() throws Exception {
2099         when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
2100         mLooper.startAutoDispatch();
2101         assertTrue(mWifiServiceImpl.is5GHzBandSupported());
2102         mLooper.stopAutoDispatchAndIgnoreExceptions();
2103         verify(mWifiNative, never()).getChannelsForBand(anyInt());
2104     }
2105 
2106     /**
2107      * Verify isWifiBandSupported for 6GHz with an overlay override config
2108      */
2109     @Test
testIsWifiBandSupported6gWithOverride()2110     public void testIsWifiBandSupported6gWithOverride() throws Exception {
2111         when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
2112         mLooper.startAutoDispatch();
2113         assertTrue(mWifiServiceImpl.is6GHzBandSupported());
2114         mLooper.stopAutoDispatchAndIgnoreExceptions();
2115         verify(mWifiNative, never()).getChannelsForBand(anyInt());
2116     }
2117 
2118     /**
2119      * Verify isWifiBandSupported for 24GHz with no overlay override config no channels
2120      */
2121     @Test
testIsWifiBandSupported24gNoOverrideNoChannels()2122     public void testIsWifiBandSupported24gNoOverrideNoChannels() throws Exception {
2123         final int[] emptyArray = {};
2124         when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
2125         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
2126         mLooper.startAutoDispatch();
2127         assertFalse(mWifiServiceImpl.is24GHzBandSupported());
2128         mLooper.stopAutoDispatch();
2129         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
2130     }
2131 
2132     /**
2133      * Verify isWifiBandSupported for 5GHz with no overlay override config no channels
2134      */
2135     @Test
testIsWifiBandSupported5gNoOverrideNoChannels()2136     public void testIsWifiBandSupported5gNoOverrideNoChannels() throws Exception {
2137         final int[] emptyArray = {};
2138         when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
2139         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
2140         mLooper.startAutoDispatch();
2141         assertFalse(mWifiServiceImpl.is5GHzBandSupported());
2142         mLooper.stopAutoDispatch();
2143         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
2144     }
2145 
2146     /**
2147      * Verify isWifiBandSupported for 24GHz with no overlay override config with channels
2148      */
2149     @Test
testIsWifiBandSupported24gNoOverrideWithChannels()2150     public void testIsWifiBandSupported24gNoOverrideWithChannels() throws Exception {
2151         final int[] channelArray = {2412};
2152         when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
2153         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
2154         mLooper.startAutoDispatch();
2155         assertTrue(mWifiServiceImpl.is24GHzBandSupported());
2156         mLooper.stopAutoDispatch();
2157         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
2158     }
2159 
2160     /**
2161      * Verify isWifiBandSupported for 5GHz with no overlay override config with channels
2162      */
2163     @Test
testIsWifiBandSupported5gNoOverrideWithChannels()2164     public void testIsWifiBandSupported5gNoOverrideWithChannels() throws Exception {
2165         final int[] channelArray = {5170};
2166         when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
2167         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
2168         mLooper.startAutoDispatch();
2169         assertTrue(mWifiServiceImpl.is5GHzBandSupported());
2170         mLooper.stopAutoDispatch();
2171         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
2172     }
2173 
2174     /**
2175      * Verify isWifiBandSupported for 6GHz with no overlay override config no channels
2176      */
2177     @Test
testIsWifiBandSupported6gNoOverrideNoChannels()2178     public void testIsWifiBandSupported6gNoOverrideNoChannels() throws Exception {
2179         final int[] emptyArray = {};
2180         when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
2181         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
2182         mLooper.startAutoDispatch();
2183         assertFalse(mWifiServiceImpl.is6GHzBandSupported());
2184         mLooper.stopAutoDispatch();
2185         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ);
2186     }
2187 
2188     /**
2189      * Verify isWifiBandSupported for 6GHz with no overlay override config with channels
2190      */
2191     @Test
testIsWifiBandSupported6gNoOverrideWithChannels()2192     public void testIsWifiBandSupported6gNoOverrideWithChannels() throws Exception {
2193         final int[] channelArray = {6420};
2194         when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
2195         when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
2196         mLooper.startAutoDispatch();
2197         assertTrue(mWifiServiceImpl.is6GHzBandSupported());
2198         mLooper.stopAutoDispatch();
2199         verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ);
2200     }
2201 
setup24GhzSupported()2202     private void setup24GhzSupported() {
2203         when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
2204         when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
2205     }
2206 
setup24GhzUnsupported(boolean isOnlyUnsupportedSoftAp)2207     private void setup24GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
2208         when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(false);
2209         if (!isOnlyUnsupportedSoftAp) {
2210             when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
2211             when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ))
2212                     .thenReturn(new int[0]);
2213         }
2214     }
2215 
setup5GhzSupported()2216     private void setup5GhzSupported() {
2217         when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
2218         when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true);
2219     }
2220 
setup5GhzUnsupported(boolean isOnlyUnsupportedSoftAp)2221     private void setup5GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
2222         when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(false);
2223         if (!isOnlyUnsupportedSoftAp) {
2224             when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
2225             when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
2226                     .thenReturn(new int[0]);
2227         }
2228     }
2229 
setup6GhzSupported()2230     private void setup6GhzSupported() {
2231         when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
2232         when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true);
2233     }
2234 
setup6GhzUnsupported(boolean isOnlyUnsupportedSoftAp)2235     private void setup6GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
2236         when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
2237         if (!isOnlyUnsupportedSoftAp) {
2238             when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
2239             when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ))
2240                     .thenReturn(new int[0]);
2241         }
2242     }
2243 
setup60GhzSupported()2244     private void setup60GhzSupported() {
2245         when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(true);
2246         when(mResources.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(true);
2247     }
2248 
setup60GhzUnsupported(boolean isOnlyUnsupportedSoftAp)2249     private void setup60GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
2250         when(mResources.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(false);
2251         if (!isOnlyUnsupportedSoftAp) {
2252             when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(false);
2253             when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ))
2254                     .thenReturn(new int[0]);
2255         }
2256     }
2257 
2258     /**
2259      * Verify attempt to start softAp with a supported 24GHz band succeeds.
2260      */
2261     @Test
testStartTetheredHotspotWithSupported24gBand()2262     public void testStartTetheredHotspotWithSupported24gBand() {
2263         setup24GhzSupported();
2264 
2265         SoftApConfiguration config = new SoftApConfiguration.Builder()
2266                 .setSsid("TestAp")
2267                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2268                 .setBand(SoftApConfiguration.BAND_2GHZ)
2269                 .build();
2270 
2271         mLooper.startAutoDispatch();
2272         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2273         mLooper.stopAutoDispatchAndIgnoreExceptions();
2274 
2275         assertTrue(result);
2276         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2277                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2278         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2279     }
2280 
2281     /**
2282      * Verify attempt to start softAp with a non-supported 2.4GHz band fails.
2283      */
2284     @Test
testStartTetheredHotspotWithUnSupported24gBand()2285     public void testStartTetheredHotspotWithUnSupported24gBand() {
2286         setup24GhzUnsupported(false);
2287 
2288         SoftApConfiguration config = new SoftApConfiguration.Builder()
2289                 .setSsid("TestAp")
2290                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2291                 .setBand(SoftApConfiguration.BAND_2GHZ)
2292                 .build();
2293 
2294         mLooper.startAutoDispatch();
2295         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2296         mLooper.stopAutoDispatchAndIgnoreExceptions();
2297 
2298         assertFalse(result);
2299         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2300     }
2301 
2302     /**
2303      * Verify attempt to start softAp with a non-supported 2.4GHz band fails.
2304      */
2305     @Test
testStartTetheredHotspotWithUnSupportedSoftAp24gBand()2306     public void testStartTetheredHotspotWithUnSupportedSoftAp24gBand() {
2307         setup24GhzSupported();
2308         setup24GhzUnsupported(true);
2309 
2310         SoftApConfiguration config = new SoftApConfiguration.Builder()
2311                 .setSsid("TestAp")
2312                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2313                 .setBand(SoftApConfiguration.BAND_2GHZ)
2314                 .build();
2315 
2316         mLooper.startAutoDispatch();
2317         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2318         mLooper.stopAutoDispatchAndIgnoreExceptions();
2319 
2320         assertFalse(result);
2321         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2322     }
2323 
2324     /**
2325      * Verify attempt to start softAp with a supported 5GHz band succeeds.
2326      */
2327     @Test
testStartTetheredHotspotWithSupported5gBand()2328     public void testStartTetheredHotspotWithSupported5gBand() {
2329         setup5GhzSupported();
2330 
2331         SoftApConfiguration config = new SoftApConfiguration.Builder()
2332                 .setSsid("TestAp")
2333                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2334                 .setBand(SoftApConfiguration.BAND_5GHZ)
2335                 .build();
2336 
2337         mLooper.startAutoDispatch();
2338         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2339         mLooper.stopAutoDispatchAndIgnoreExceptions();
2340 
2341         assertTrue(result);
2342         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2343                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2344         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2345     }
2346 
2347     /**
2348      * Verify attempt to start softAp with a non-supported 5GHz band fails.
2349      */
2350     @Test
testStartTetheredHotspotWithUnSupported5gBand()2351     public void testStartTetheredHotspotWithUnSupported5gBand() {
2352         setup5GhzUnsupported(false);
2353 
2354         SoftApConfiguration config = new SoftApConfiguration.Builder()
2355                 .setSsid("TestAp")
2356                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2357                 .setBand(SoftApConfiguration.BAND_5GHZ)
2358                 .build();
2359 
2360         mLooper.startAutoDispatch();
2361         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2362         mLooper.stopAutoDispatchAndIgnoreExceptions();
2363 
2364         assertFalse(result);
2365         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2366     }
2367 
2368     /**
2369      * Verify attempt to start softAp with a non-supported 5GHz band fails.
2370      */
2371     @Test
testStartTetheredHotspotWithUnSupportedSoftAp5gBand()2372     public void testStartTetheredHotspotWithUnSupportedSoftAp5gBand() {
2373         setup5GhzSupported();
2374         setup5GhzUnsupported(true);
2375 
2376         SoftApConfiguration config = new SoftApConfiguration.Builder()
2377                 .setSsid("TestAp")
2378                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2379                 .setBand(SoftApConfiguration.BAND_5GHZ)
2380                 .build();
2381 
2382         mLooper.startAutoDispatch();
2383         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2384         mLooper.stopAutoDispatchAndIgnoreExceptions();
2385 
2386         assertFalse(result);
2387         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2388     }
2389 
2390     /**
2391      * Verify attempt to start softAp with a supported 6GHz band succeeds.
2392      */
2393     @Test
testStartTetheredHotspotWithSupported6gBand()2394     public void testStartTetheredHotspotWithSupported6gBand() {
2395         setup6GhzSupported();
2396 
2397         SoftApConfiguration config = new SoftApConfiguration.Builder()
2398                 .setSsid("TestAp")
2399                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
2400                 .setBand(SoftApConfiguration.BAND_6GHZ)
2401                 .build();
2402 
2403         mLooper.startAutoDispatch();
2404         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2405         mLooper.stopAutoDispatchAndIgnoreExceptions();
2406 
2407         assertTrue(result);
2408         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2409                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2410         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2411     }
2412 
2413     /**
2414      * Verify attempt to start softAp with a non-supported 6GHz band fails.
2415      */
2416     @Test
testStartTetheredHotspotWithUnSupported6gBand()2417     public void testStartTetheredHotspotWithUnSupported6gBand() {
2418         setup6GhzUnsupported(false);
2419 
2420         SoftApConfiguration config = new SoftApConfiguration.Builder()
2421                 .setSsid("TestAp")
2422                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
2423                 .setBand(SoftApConfiguration.BAND_6GHZ)
2424                 .build();
2425 
2426         mLooper.startAutoDispatch();
2427         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2428         mLooper.stopAutoDispatchAndIgnoreExceptions();
2429 
2430         assertFalse(result);
2431         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2432     }
2433 
2434     /**
2435      * Verify attempt to start softAp with a non-supported 6GHz band fails.
2436      */
2437     @Test
testStartTetheredHotspotWithUnSupportedSoftAp6gBand()2438     public void testStartTetheredHotspotWithUnSupportedSoftAp6gBand() {
2439         setup6GhzSupported();
2440         setup6GhzUnsupported(true);
2441 
2442         SoftApConfiguration config = new SoftApConfiguration.Builder()
2443                 .setSsid("TestAp")
2444                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
2445                 .setBand(SoftApConfiguration.BAND_6GHZ)
2446                 .build();
2447 
2448         mLooper.startAutoDispatch();
2449         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2450         mLooper.stopAutoDispatchAndIgnoreExceptions();
2451 
2452         assertFalse(result);
2453         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2454     }
2455 
2456 
2457     /**
2458      * Verify attempt to start softAp with a supported 60GHz band succeeds.
2459      */
2460     @Test
testStartTetheredHotspotWithSupported60gBand()2461     public void testStartTetheredHotspotWithSupported60gBand() {
2462         setup60GhzSupported();
2463 
2464         SoftApConfiguration config = new SoftApConfiguration.Builder()
2465                 .setSsid("TestAp")
2466                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2467                 .setBand(SoftApConfiguration.BAND_60GHZ)
2468                 .build();
2469 
2470         mLooper.startAutoDispatch();
2471         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2472         mLooper.stopAutoDispatchAndIgnoreExceptions();
2473 
2474         assertTrue(result);
2475         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2476                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2477         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2478     }
2479 
2480     /**
2481      * Verify attempt to start softAp with a non-supported 60GHz band fails.
2482      */
2483     @Test
testStartTetheredHotspotWithUnSupported60gBand()2484     public void testStartTetheredHotspotWithUnSupported60gBand() {
2485         setup60GhzUnsupported(false);
2486 
2487         SoftApConfiguration config = new SoftApConfiguration.Builder()
2488                 .setSsid("TestAp")
2489                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2490                 .setBand(SoftApConfiguration.BAND_60GHZ)
2491                 .build();
2492 
2493         mLooper.startAutoDispatch();
2494         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2495         mLooper.stopAutoDispatchAndIgnoreExceptions();
2496 
2497         assertFalse(result);
2498         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2499     }
2500 
2501     /**
2502      * Verify attempt to start softAp with a non-supported 60GHz band fails.
2503      */
2504     @Test
testStartTetheredHotspotWithUnSupportedSoftAp60gBand()2505     public void testStartTetheredHotspotWithUnSupportedSoftAp60gBand() {
2506         setup60GhzSupported();
2507         setup60GhzUnsupported(true);
2508 
2509         SoftApConfiguration config = new SoftApConfiguration.Builder()
2510                 .setSsid("TestAp")
2511                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2512                 .setBand(SoftApConfiguration.BAND_60GHZ)
2513                 .build();
2514 
2515         mLooper.startAutoDispatch();
2516         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2517         mLooper.stopAutoDispatchAndIgnoreExceptions();
2518 
2519         assertFalse(result);
2520         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2521     }
2522 
2523     /**
2524      * Verify attempt to start softAp with a supported band succeeds.
2525      */
2526     @Test
testStartTetheredHotspotWithSupportedBand()2527     public void testStartTetheredHotspotWithSupportedBand() {
2528         setup5GhzSupported();
2529 
2530         SoftApConfiguration config = new SoftApConfiguration.Builder()
2531                 .setSsid("TestAp")
2532                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
2533                 .setBand(SoftApConfiguration.BAND_5GHZ)
2534                 .build();
2535 
2536         mLooper.startAutoDispatch();
2537         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2538         mLooper.stopAutoDispatchAndIgnoreExceptions();
2539 
2540         assertTrue(result);
2541         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2542                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2543         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2544     }
2545 
2546     /**
2547      * Verify a SecurityException is thrown when a caller without the correct permission attempts to
2548      * start softap.
2549      */
2550     @Test(expected = SecurityException.class)
testStartTetheredHotspotWithoutPermissionThrowsException()2551     public void testStartTetheredHotspotWithoutPermissionThrowsException() throws Exception {
2552         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
2553                 .thenReturn(PackageManager.PERMISSION_DENIED);
2554         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
2555                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
2556         mWifiServiceImpl.startTetheredHotspot(null, TEST_PACKAGE_NAME);
2557     }
2558 
2559     /**
2560      * Verify that startTetheredHotspot() succeeds if the caller does not have the
2561      * NETWORK_STACK permission but does have the MAINLINE_NETWORK_STACK permission.
2562      */
2563     @Test
testStartTetheredHotspotWithoutNetworkStackWithMainlineNetworkStackSucceeds()2564     public void testStartTetheredHotspotWithoutNetworkStackWithMainlineNetworkStackSucceeds() {
2565         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
2566                 .thenReturn(PackageManager.PERMISSION_DENIED);
2567         SoftApConfiguration config = createValidSoftApConfiguration();
2568         mLooper.startAutoDispatch();
2569         boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
2570         assertTrue(result);
2571         mLooper.stopAutoDispatchAndIgnoreExceptions();
2572         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2573                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2574         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2575         verify(mContext).enforceCallingOrSelfPermission(
2576                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
2577     }
2578 
2579     /**
2580      * Verify a valied call to startTetheredHotspot succeeds after a failed call.
2581      */
2582     @Test
testStartTetheredHotspotWithValidConfigSucceedsAfterFailedCall()2583     public void testStartTetheredHotspotWithValidConfigSucceedsAfterFailedCall() {
2584         // First issue an invalid call
2585         mLooper.startAutoDispatch();
2586         assertFalse(mWifiServiceImpl.startTetheredHotspot(
2587                 new SoftApConfiguration.Builder().build(), TEST_PACKAGE_NAME));
2588         mLooper.stopAutoDispatchAndIgnoreExceptions();
2589         verify(mActiveModeWarden, never()).startSoftAp(any(), any());
2590 
2591         // Now attempt a successful call
2592         mLooper.startAutoDispatch();
2593         assertTrue(mWifiServiceImpl.startTetheredHotspot(null, TEST_PACKAGE_NAME));
2594         mLooper.stopAutoDispatchAndIgnoreExceptions();
2595         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
2596                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
2597         assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
2598     }
2599 
2600     /**
2601      * Verify caller with proper permission can call stopSoftAp.
2602      */
2603     @Test
testStopSoftApWithPermissions()2604     public void testStopSoftApWithPermissions() {
2605         boolean result = mWifiServiceImpl.stopSoftAp();
2606         assertTrue(result);
2607         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED);
2608         verify(mLastCallerInfoManager).put(eq(WifiManager.API_SOFT_AP), anyInt(),
2609                 anyInt(), anyInt(), anyString(), eq(false));
2610     }
2611 
2612     /**
2613      * Verify SecurityException is thrown when a caller without the correct permission attempts to
2614      * stop softap.
2615      */
2616     @Test(expected = SecurityException.class)
testStopSoftApWithoutPermissionThrowsException()2617     public void testStopSoftApWithoutPermissionThrowsException() throws Exception {
2618         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
2619                 .thenReturn(PackageManager.PERMISSION_DENIED);
2620         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
2621                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
2622         mWifiServiceImpl.stopSoftAp();
2623     }
2624 
2625     /**
2626      * Ensure that we handle app ops check failure when handling scan request.
2627      */
2628     @Test
testStartScanFailureAppOpsIgnored()2629     public void testStartScanFailureAppOpsIgnored() {
2630         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
2631                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME);
2632         mLooper.startAutoDispatch();
2633         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
2634         mLooper.stopAutoDispatchAndIgnoreExceptions();
2635         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
2636     }
2637 
2638     /**
2639      * Ensure that we handle scan access permission check failure when handling scan request.
2640      */
2641     @Test
testStartScanFailureInCanAccessScanResultsPermission()2642     public void testStartScanFailureInCanAccessScanResultsPermission() {
2643         doThrow(new SecurityException()).when(mWifiPermissionsUtil)
2644                 .enforceCanAccessScanResults(SCAN_PACKAGE_NAME, TEST_FEATURE_ID, Process.myUid(),
2645                         null);
2646         mLooper.startAutoDispatch();
2647         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
2648         mLooper.stopAutoDispatchAndIgnoreExceptions();
2649         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
2650     }
2651 
2652     /**
2653      * Ensure that we handle scan request failure when posting the runnable to handler fails.
2654      */
2655     @Test
testStartScanFailureInRunWithScissors()2656     public void testStartScanFailureInRunWithScissors() {
2657         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
2658 
2659         mLooper.startAutoDispatch();
2660         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
2661         mLooper.stopAutoDispatchAndIgnoreExceptions();
2662         verify(mScanRequestProxy, never()).startScan(anyInt(), eq(SCAN_PACKAGE_NAME));
2663     }
2664 
2665     /**
2666      * Ensure that we handle scan request failure from ScanRequestProxy fails.
2667      */
2668     @Test
testStartScanFailureFromScanRequestProxy()2669     public void testStartScanFailureFromScanRequestProxy() {
2670         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false);
2671 
2672         mLooper.startAutoDispatch();
2673         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
2674         mLooper.stopAutoDispatchAndIgnoreExceptions();
2675         verify(mScanRequestProxy).startScan(Binder.getCallingUid(), SCAN_PACKAGE_NAME);
2676     }
2677 
setupForGetConnectionInfo()2678     private WifiInfo setupForGetConnectionInfo() {
2679         WifiInfo wifiInfo = new WifiInfo();
2680         wifiInfo.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
2681         wifiInfo.setBSSID(TEST_BSSID);
2682         wifiInfo.setNetworkId(TEST_NETWORK_ID);
2683         wifiInfo.setFQDN(TEST_FQDN);
2684         wifiInfo.setProviderFriendlyName(TEST_FRIENDLY_NAME);
2685         return wifiInfo;
2686     }
2687 
parcelingRoundTrip(WifiInfo wifiInfo)2688     private WifiInfo parcelingRoundTrip(WifiInfo wifiInfo) {
2689         Parcel parcel = Parcel.obtain();
2690         wifiInfo.writeToParcel(parcel, 0);
2691         // Rewind the pointer to the head of the parcel.
2692         parcel.setDataPosition(0);
2693         return WifiInfo.CREATOR.createFromParcel(parcel);
2694     }
2695 
2696     /**
2697      * Test that connected SSID and BSSID are not exposed to an app that does not have the
2698      * appropriate permissions.
2699      */
2700     @Test
testConnectedIdsAreHiddenFromAppWithoutPermission()2701     public void testConnectedIdsAreHiddenFromAppWithoutPermission() throws Exception {
2702         WifiInfo wifiInfo = setupForGetConnectionInfo();
2703         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
2704 
2705         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
2706                 anyString(), nullable(String.class), anyInt(), nullable(String.class));
2707 
2708         mLooper.startAutoDispatch();
2709         WifiInfo connectionInfo = parcelingRoundTrip(
2710                 mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE, TEST_FEATURE_ID));
2711         mLooper.stopAutoDispatchAndIgnoreExceptions();
2712 
2713         assertEquals(WifiManager.UNKNOWN_SSID, connectionInfo.getSSID());
2714         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
2715         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, connectionInfo.getNetworkId());
2716         assertNull(connectionInfo.getPasspointFqdn());
2717         assertNull(connectionInfo.getPasspointProviderFriendlyName());
2718         if (SdkLevel.isAtLeastS()) {
2719             try {
2720                 connectionInfo.isPrimary();
2721                 fail();
2722             } catch (SecurityException e) { /* pass */ }
2723         }
2724     }
2725 
2726     /**
2727      * Test that connected SSID and BSSID are not exposed to an app that does not have the
2728      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
2729      */
2730     @Test
testConnectedIdsAreHiddenOnSecurityException()2731     public void testConnectedIdsAreHiddenOnSecurityException() throws Exception {
2732         WifiInfo wifiInfo = setupForGetConnectionInfo();
2733         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
2734 
2735         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
2736                 anyString(), nullable(String.class), anyInt(), nullable(String.class));
2737 
2738         mLooper.startAutoDispatch();
2739         WifiInfo connectionInfo = parcelingRoundTrip(
2740                 mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE, TEST_FEATURE_ID));
2741         mLooper.stopAutoDispatchAndIgnoreExceptions();
2742 
2743         assertEquals(WifiManager.UNKNOWN_SSID, connectionInfo.getSSID());
2744         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
2745         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, connectionInfo.getNetworkId());
2746         assertNull(connectionInfo.getPasspointFqdn());
2747         assertNull(connectionInfo.getPasspointProviderFriendlyName());
2748     }
2749 
2750     /**
2751      * Test that connected SSID and BSSID are exposed to an app that does have the
2752      * appropriate permissions.
2753      */
2754     @Test
testConnectedIdsAreVisibleFromPermittedApp()2755     public void testConnectedIdsAreVisibleFromPermittedApp() throws Exception {
2756         WifiInfo wifiInfo = setupForGetConnectionInfo();
2757         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
2758 
2759         mLooper.startAutoDispatch();
2760         WifiInfo connectionInfo = parcelingRoundTrip(
2761                 mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE, TEST_FEATURE_ID));
2762         mLooper.stopAutoDispatchAndIgnoreExceptions();
2763 
2764         assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID());
2765         assertEquals(TEST_BSSID, connectionInfo.getBSSID());
2766         assertEquals(TEST_NETWORK_ID, connectionInfo.getNetworkId());
2767         assertEquals(TEST_FQDN, connectionInfo.getPasspointFqdn());
2768         assertEquals(TEST_FRIENDLY_NAME, connectionInfo.getPasspointProviderFriendlyName());
2769     }
2770 
2771     /**
2772      * Test that connected SSID and BSSID for secondary CMM are exposed to an app that requests
2773      * the second STA on a device that supports STA + STA.
2774      */
2775     @Test
testConnectedIdsFromSecondaryCmmAreVisibleFromAppRequestingSecondaryCmm()2776     public void testConnectedIdsFromSecondaryCmmAreVisibleFromAppRequestingSecondaryCmm()
2777             throws Exception {
2778         WifiInfo wifiInfo = setupForGetConnectionInfo();
2779         ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
2780         when(secondaryCmm.getRequestorWs())
2781                 .thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE));
2782         when(secondaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo);
2783         when(mActiveModeWarden.getClientModeManagersInRoles(
2784                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
2785                 .thenReturn(Arrays.asList(secondaryCmm));
2786 
2787         mLooper.startAutoDispatch();
2788         WifiInfo connectionInfo = parcelingRoundTrip(
2789                 mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE, TEST_FEATURE_ID));
2790         mLooper.stopAutoDispatchAndIgnoreExceptions();
2791 
2792         assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID());
2793         assertEquals(TEST_BSSID, connectionInfo.getBSSID());
2794         assertEquals(TEST_NETWORK_ID, connectionInfo.getNetworkId());
2795         assertEquals(TEST_FQDN, connectionInfo.getPasspointFqdn());
2796         assertEquals(TEST_FRIENDLY_NAME, connectionInfo.getPasspointProviderFriendlyName());
2797     }
2798 
2799     /**
2800      * Test that connected SSID and BSSID for primary CMM are exposed to an app that is not the one
2801      * that requests the second STA on a device that supports STA + STA.
2802      */
2803     @Test
testConnectedIdsFromPrimaryCmmAreVisibleFromAppNotRequestingSecondaryCmm()2804     public void testConnectedIdsFromPrimaryCmmAreVisibleFromAppNotRequestingSecondaryCmm()
2805             throws Exception {
2806         WifiInfo wifiInfo = setupForGetConnectionInfo();
2807         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
2808         ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
2809         when(secondaryCmm.getRequestorWs())
2810                 .thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME_OTHER));
2811         when(mActiveModeWarden.getClientModeManagersInRoles(
2812                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
2813                 .thenReturn(Arrays.asList(secondaryCmm));
2814 
2815         mLooper.startAutoDispatch();
2816         WifiInfo connectionInfo = parcelingRoundTrip(
2817                 mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE, TEST_FEATURE_ID));
2818         mLooper.stopAutoDispatchAndIgnoreExceptions();
2819 
2820         assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID());
2821         assertEquals(TEST_BSSID, connectionInfo.getBSSID());
2822         assertEquals(TEST_NETWORK_ID, connectionInfo.getNetworkId());
2823         assertEquals(TEST_FQDN, connectionInfo.getPasspointFqdn());
2824         assertEquals(TEST_FRIENDLY_NAME, connectionInfo.getPasspointProviderFriendlyName());
2825     }
2826 
2827     /**
2828      * Test that configured network list are exposed empty list to an app that does not have the
2829      * appropriate permissions.
2830      */
2831     @Test
testConfiguredNetworkListAreEmptyFromAppWithoutPermission()2832     public void testConfiguredNetworkListAreEmptyFromAppWithoutPermission() throws Exception {
2833         when(mWifiConfigManager.getSavedNetworks(anyInt()))
2834                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
2835 
2836         // no permission = target SDK=Q && not a carrier app
2837         when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(anyString())).thenReturn(
2838                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
2839 
2840         ParceledListSlice<WifiConfiguration> configs =
2841                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
2842 
2843         assertEquals(0, configs.getList().size());
2844     }
2845 
2846     /**
2847      * Test that configured network list are exposed empty list to an app that does not have the
2848      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
2849      */
2850     @Test
testConfiguredNetworkListAreEmptyOnSecurityException()2851     public void testConfiguredNetworkListAreEmptyOnSecurityException() throws Exception {
2852         when(mWifiConfigManager.getSavedNetworks(anyInt()))
2853                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
2854 
2855         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
2856                 anyString(), nullable(String.class), anyInt(), nullable(String.class));
2857 
2858         ParceledListSlice<WifiConfiguration> configs =
2859                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
2860 
2861         assertEquals(0, configs.getList().size());
2862 
2863     }
2864 
2865     /**
2866      * Test that configured network list are exposed to an app that does have the
2867      * appropriate permissions.
2868      */
2869     @Test
testConfiguredNetworkListAreVisibleFromPermittedApp()2870     public void testConfiguredNetworkListAreVisibleFromPermittedApp() throws Exception {
2871         when(mWifiConfigManager.getSavedNetworks(anyInt()))
2872                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
2873 
2874         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2875                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2876 
2877         mLooper.startAutoDispatch();
2878         ParceledListSlice<WifiConfiguration> configs =
2879                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
2880         mLooper.stopAutoDispatchAndIgnoreExceptions();
2881 
2882         verify(mWifiConfigManager).getSavedNetworks(eq(Process.WIFI_UID));
2883         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
2884                 TEST_WIFI_CONFIGURATION_LIST, configs.getList());
2885     }
2886 
2887     @Test(expected = SecurityException.class)
testGetCallerConfiguredNetworks_ThrowExceptionIfNotDoOrPO()2888     public void testGetCallerConfiguredNetworks_ThrowExceptionIfNotDoOrPO() {
2889         when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2890                 .thenReturn(false);
2891         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2892                 .thenReturn(false);
2893 
2894         mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE_NAME, TEST_FEATURE_ID, true);
2895     }
2896 
2897     @Test
testGetCallerConfiguredNetworks_ReturnsCallerNetworks()2898     public void testGetCallerConfiguredNetworks_ReturnsCallerNetworks() {
2899         final int callerUid = Binder.getCallingUid();
2900         WifiConfiguration callerNetwork0 = WifiConfigurationTestUtil.generateWifiConfig(
2901                 0, callerUid, "\"red\"", true, true, null, null, SECURITY_NONE);
2902         WifiConfiguration callerNetwork1 = WifiConfigurationTestUtil.generateWifiConfig(
2903                 1, callerUid, "\"red\"", true, true, null, null, SECURITY_NONE);
2904         WifiConfiguration nonCallerNetwork0 = WifiConfigurationTestUtil.generateWifiConfig(
2905                 2, 1200000, "\"blue\"", false, true, null, null, SECURITY_NONE);
2906         WifiConfiguration nonCallerNetwork1 = WifiConfigurationTestUtil.generateWifiConfig(
2907                 3, 1100000, "\"cyan\"", true, true, null, null, SECURITY_NONE);
2908         when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(
2909                 callerNetwork0, callerNetwork1, nonCallerNetwork0, nonCallerNetwork1));
2910 
2911         // Caller does NOT need to have location permission to be able to retrieve its own networks.
2912         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
2913                 anyString(), nullable(String.class), anyInt(), nullable(String.class));
2914         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2915                 .thenReturn(true);
2916         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2917                 .thenReturn(true);
2918 
2919         mLooper.startAutoDispatch();
2920         ParceledListSlice<WifiConfiguration> configs =
2921                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE_NAME, TEST_FEATURE_ID, true);
2922         mLooper.stopAutoDispatchAndIgnoreExceptions();
2923 
2924         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
2925                 Arrays.asList(callerNetwork0, callerNetwork1), configs.getList());
2926     }
2927 
2928     /**
2929      * Test that admin may retrieve all networks but mac address is set to default for networks
2930      * they do not own.
2931      */
2932     @Test
testGetConfiguredNetworksAdmin_ReturnsNetworksWithDefaultMac()2933     public void testGetConfiguredNetworksAdmin_ReturnsNetworksWithDefaultMac() {
2934         final int callerUid = Binder.getCallingUid();
2935         WifiConfiguration callerNetwork = WifiConfigurationTestUtil.generateWifiConfig(
2936                 0, callerUid, "\"red\"", true, true, null, null, SECURITY_NONE);
2937         WifiConfiguration nonCallerNetwork = WifiConfigurationTestUtil.generateWifiConfig(
2938                 2, 1200000, "\"blue\"", true, true, null, null, SECURITY_NONE);
2939         callerNetwork.setRandomizedMacAddress(TEST_FACTORY_MAC_ADDR);
2940 
2941         when(mWifiConfigManager.getSavedNetworks(callerUid)).thenReturn(Arrays.asList(
2942                 callerNetwork, nonCallerNetwork));
2943 
2944         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2945                 .thenReturn(true);
2946         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
2947                 .thenReturn(true);
2948 
2949         mLooper.startAutoDispatch();
2950         ParceledListSlice<WifiConfiguration> configs =
2951                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE_NAME, TEST_FEATURE_ID, false);
2952         mLooper.stopAutoDispatchAndIgnoreExceptions();
2953 
2954         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
2955                 Arrays.asList(callerNetwork, nonCallerNetwork), configs.getList());
2956 
2957         for (WifiConfiguration config : configs.getList()) {
2958             if (config.getProfileKey().equals(callerNetwork.getProfileKey())) {
2959                 assertEquals(TEST_FACTORY_MAC, config.getRandomizedMacAddress().toString());
2960             } else {
2961                 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS,
2962                         config.getRandomizedMacAddress().toString());
2963             }
2964         }
2965     }
2966 
2967     /**
2968      * Test that privileged network list are exposed null to an app that targets T or later and does
2969      * not have nearby devices permission.
2970      */
2971     @Test
testPrivilegedConfiguredNetworkListNullOnSecurityExceptionPostT()2972     public void testPrivilegedConfiguredNetworkListNullOnSecurityExceptionPostT() {
2973         assumeTrue(SdkLevel.isAtLeastT());
2974         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
2975                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(false);
2976         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
2977                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
2978 
2979         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
2980                 any(), anyBoolean(), any());
2981 
2982         mLooper.startAutoDispatch();
2983         ParceledListSlice<WifiConfiguration> configs =
2984                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
2985                         mExtras);
2986         mLooper.stopAutoDispatchAndIgnoreExceptions();
2987 
2988         assertNull(configs);
2989     }
2990 
2991     /**
2992      * Test that privileged network list are exposed null to an app that does not have the
2993      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
2994      */
2995     @Test
testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException()2996     public void testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException() {
2997         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
2998                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
2999 
3000         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
3001                 anyString(), nullable(String.class), anyInt(), nullable(String.class));
3002 
3003         mLooper.startAutoDispatch();
3004         ParceledListSlice<WifiConfiguration> configs =
3005                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
3006                         mExtras);
3007         mLooper.stopAutoDispatchAndIgnoreExceptions();
3008 
3009         assertNull(configs);
3010     }
3011 
3012     /**
3013      * Test that privileged network list are exposed to an app that does have the
3014      * appropriate permissions (simulated by not throwing an exception for READ_WIFI_CREDENTIAL).
3015      */
3016     @Test
testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp()3017     public void testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp() {
3018         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
3019                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
3020 
3021         mLooper.startAutoDispatch();
3022         ParceledListSlice<WifiConfiguration> configs =
3023                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
3024                         mExtras);
3025         mLooper.stopAutoDispatchAndIgnoreExceptions();
3026 
3027         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
3028                 TEST_WIFI_CONFIGURATION_LIST, configs.getList());
3029     }
3030 
3031     /**
3032      * Test fetching of scan results.
3033      */
3034     @Test
testGetScanResults()3035     public void testGetScanResults() {
3036         ScanResult[] scanResults =
3037                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
3038                         .getResults();
3039         List<ScanResult> scanResultList =
3040                 new ArrayList<>(Arrays.asList(scanResults));
3041         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
3042 
3043         String packageName = "test.com";
3044         String featureId = "test.com.featureId";
3045         mLooper.startAutoDispatch();
3046         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName,
3047                 featureId);
3048         mLooper.stopAutoDispatchAndIgnoreExceptions();
3049         verify(mScanRequestProxy).getScanResults();
3050 
3051         ScanTestUtil.assertScanResultsEquals(scanResults,
3052                 retrievedScanResultList.toArray(new ScanResult[retrievedScanResultList.size()]));
3053     }
3054 
3055     /**
3056      * Ensure that we handle scan results failure when posting the runnable to handler fails.
3057      */
3058     @Test
testGetScanResultsFailureInRunWithScissors()3059     public void testGetScanResultsFailureInRunWithScissors() {
3060         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
3061 
3062         ScanResult[] scanResults =
3063                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
3064                         .getResults();
3065         List<ScanResult> scanResultList =
3066                 new ArrayList<>(Arrays.asList(scanResults));
3067         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
3068 
3069         String packageName = "test.com";
3070         String featureId = "test.com.featureId";
3071         mLooper.startAutoDispatch();
3072         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName,
3073                 featureId);
3074         mLooper.stopAutoDispatchAndIgnoreExceptions();
3075         verify(mScanRequestProxy, never()).getScanResults();
3076 
3077         assertTrue(retrievedScanResultList.isEmpty());
3078     }
3079 
3080     /**
3081      * Test fetching of matching scan results with provided WifiNetworkSuggestion, but it doesn't
3082      * specify the scan results to be filtered.
3083      */
3084     @Test
testGetMatchingScanResultsWithoutSpecifiedScanResults()3085     public void testGetMatchingScanResultsWithoutSpecifiedScanResults() {
3086         ScanResult[] scanResults =
3087                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
3088                         .getResults();
3089         List<ScanResult> scanResultList =
3090                 new ArrayList<>(Arrays.asList(scanResults));
3091         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
3092         WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
3093         List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
3094                 add(mockSuggestion);
3095             }};
3096         Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
3097                 put(mockSuggestion, scanResultList);
3098             }};
3099         when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
3100                 eq(scanResultList))).thenReturn(result);
3101 
3102         String packageName = "test.com";
3103         String featureId = "test.com.featureId";
3104         mLooper.startAutoDispatch();
3105         Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
3106                 mWifiServiceImpl.getMatchingScanResults(
3107                         matchingSuggestions, null, packageName, featureId);
3108         mLooper.stopAutoDispatchAndIgnoreExceptions();
3109 
3110         ScanTestUtil.assertScanResultsEquals(scanResults,
3111                 retrievedScanResults.get(mockSuggestion)
3112                         .toArray(new ScanResult[retrievedScanResults.size()]));
3113     }
3114 
3115     /**
3116      * Test fetching of matching scan results with provided WifiNetworkSuggestion and ScanResults.
3117      */
3118     @Test
testGetMatchingScanResultsWithSpecifiedScanResults()3119     public void testGetMatchingScanResultsWithSpecifiedScanResults() {
3120         ScanResult[] scanResults =
3121                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
3122                         .getResults();
3123         List<ScanResult> scanResultList =
3124                 new ArrayList<>(Arrays.asList(scanResults));
3125         WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
3126         List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
3127                 add(mockSuggestion);
3128             }};
3129         Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
3130                 put(mockSuggestion, scanResultList);
3131             }};
3132         when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
3133                 eq(scanResultList))).thenReturn(result);
3134 
3135         String packageName = "test.com";
3136         String featureId = "test.com.featureId";
3137         mLooper.startAutoDispatch();
3138         Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
3139                 mWifiServiceImpl.getMatchingScanResults(
3140                         matchingSuggestions, scanResultList, packageName, featureId);
3141         mLooper.stopAutoDispatchAndIgnoreExceptions();
3142 
3143         ScanTestUtil.assertScanResultsEquals(scanResults,
3144                 retrievedScanResults.get(mockSuggestion)
3145                         .toArray(new ScanResult[retrievedScanResults.size()]));
3146     }
3147 
3148     /**
3149      * Ensure that we handle failure when posting the runnable to handler fails.
3150      */
3151     @Test
testGetMatchingScanResultsFailureInRunWithScissors()3152     public void testGetMatchingScanResultsFailureInRunWithScissors() {
3153         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
3154 
3155         ScanResult[] scanResults =
3156                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
3157                         .getResults();
3158         List<ScanResult> scanResultList =
3159                 new ArrayList<>(Arrays.asList(scanResults));
3160         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
3161         WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
3162         List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
3163                 add(mockSuggestion);
3164             }};
3165         Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
3166                 put(mockSuggestion, scanResultList);
3167             }};
3168         when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
3169                 eq(scanResultList))).thenReturn(result);
3170 
3171         String packageName = "test.com";
3172         String featureId = "test.com.featureId";
3173         mLooper.startAutoDispatch();
3174         Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
3175                 mWifiServiceImpl.getMatchingScanResults(
3176                         matchingSuggestions, null, packageName, featureId);
3177         mLooper.stopAutoDispatchAndIgnoreExceptions();
3178 
3179         assertTrue(retrievedScanResults.isEmpty());
3180     }
3181 
setupLohsPermissions()3182     private void setupLohsPermissions() {
3183         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
3184         when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
3185         when(mUserManager.hasUserRestrictionForUser(
3186                 eq(UserManager.DISALLOW_CONFIG_TETHERING), any()))
3187                 .thenReturn(false);
3188     }
3189 
registerLOHSRequestFull()3190     private void registerLOHSRequestFull() {
3191         setupLohsPermissions();
3192         int result = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME,
3193                 TEST_FEATURE_ID, null, mExtras);
3194         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
3195         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3196     }
3197 
3198     /**
3199      * Verify that the call to startLocalOnlyHotspot returns REQUEST_REGISTERED when successfully
3200      * called.
3201      */
3202     @Test
testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered()3203     public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() {
3204         mLooper.startAutoDispatch();
3205         registerLOHSRequestFull();
3206         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3207         // Use settings worksouce.
3208         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
3209                 eq(TEST_SETTINGS_WORKSOURCE));
3210     }
3211 
3212     /**
3213      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
3214      * have the CHANGE_WIFI_STATE permission.
3215      */
3216     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission()3217     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() {
3218         doThrow(new SecurityException()).when(mContext)
3219                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
3220                                                 eq("WifiService"));
3221         mWifiServiceImpl.startLocalOnlyHotspot(
3222                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3223     }
3224 
3225     /**
3226      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
3227      * have Location permission.
3228      */
3229     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission()3230     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission() {
3231         doThrow(new SecurityException())
3232                 .when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME),
3233                                                                       eq(TEST_FEATURE_ID),
3234                                                                       anyInt());
3235         mWifiServiceImpl.startLocalOnlyHotspot(
3236                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3237     }
3238 
3239     /**
3240      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller targets
3241      * Android T or later and does not have nearby devices permission.
3242      */
3243     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsExceptionWithoutNearbyDevicesPermissionOnT()3244     public void testStartLocalOnlyHotspotThrowsExceptionWithoutNearbyDevicesPermissionOnT() {
3245         assumeTrue(SdkLevel.isAtLeastT());
3246         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
3247                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(false);
3248         doThrow(new SecurityException())
3249                 .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
3250                         any(), anyBoolean(), any());
3251         mWifiServiceImpl.startLocalOnlyHotspot(
3252                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3253     }
3254 
3255     /**
3256      * Verify that a call to startLocalOnlyHotspot will not check nearby devices permission if the
3257      * caller does not target T.
3258      */
3259     @Test
testStartLocalOnlyHotspotDoesNotCheckNearbyPermissionIfTargetPreT()3260     public void testStartLocalOnlyHotspotDoesNotCheckNearbyPermissionIfTargetPreT() {
3261         assumeTrue(SdkLevel.isAtLeastT());
3262         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
3263         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
3264                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(true);
3265         mWifiServiceImpl.startLocalOnlyHotspot(
3266                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3267         verify(mWifiPermissionsUtil, never()).enforceNearbyDevicesPermission(any(), anyBoolean(),
3268                 any());
3269     }
3270 
3271     /**
3272      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if Location mode is
3273      * disabled.
3274      */
3275     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled()3276     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() {
3277         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
3278         mWifiServiceImpl.startLocalOnlyHotspot(
3279                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3280     }
3281 
3282     /**
3283      * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request.
3284      */
3285     @Test
testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp()3286     public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
3287         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
3288 
3289         when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
3290         int result = mWifiServiceImpl.startLocalOnlyHotspot(
3291                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3292         assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
3293     }
3294 
3295     /**
3296      * Only start tethering if we are not tethering.
3297      */
3298     @Test
testTetheringDoesNotStartWhenAlreadyTetheringActive()3299     public void testTetheringDoesNotStartWhenAlreadyTetheringActive() throws Exception {
3300         WifiConfiguration config = createValidWifiApConfiguration();
3301         mLooper.startAutoDispatch();
3302         assertTrue(mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME));
3303         mLooper.stopAutoDispatchAndIgnoreExceptions();
3304         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
3305                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3306         WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
3307                 config,
3308                 mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
3309         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3310         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
3311         mLooper.dispatchAll();
3312         assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState());
3313         reset(mActiveModeWarden);
3314 
3315         // Start another session without a stop, that should fail.
3316         mLooper.startAutoDispatch();
3317         assertFalse(mWifiServiceImpl.startSoftAp(
3318                 createValidWifiApConfiguration(), TEST_PACKAGE_NAME));
3319         mLooper.stopAutoDispatchAndIgnoreExceptions();
3320 
3321         verifyNoMoreInteractions(mActiveModeWarden);
3322     }
3323 
3324     /**
3325      * Only start tethering if we are not tethering in new API: startTetheredHotspot.
3326      */
3327     @Test
testStartTetheredHotspotDoesNotStartWhenAlreadyTetheringActive()3328     public void testStartTetheredHotspotDoesNotStartWhenAlreadyTetheringActive() throws Exception {
3329         SoftApConfiguration config = createValidSoftApConfiguration();
3330         mLooper.startAutoDispatch();
3331         assertTrue(mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME));
3332         mLooper.stopAutoDispatch();
3333         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
3334                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3335         assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
3336         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3337         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
3338         mLooper.dispatchAll();
3339         assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState());
3340         reset(mActiveModeWarden);
3341 
3342         // Start another session without a stop, that should fail.
3343         mLooper.startAutoDispatch();
3344         assertFalse(mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME));
3345         mLooper.stopAutoDispatchAndIgnoreExceptions();
3346 
3347         verifyNoMoreInteractions(mActiveModeWarden);
3348     }
3349 
3350     /**
3351      * Only start LocalOnlyHotspot if we are not tethering.
3352      */
3353     @Test
testHotspotDoesNotStartWhenAlreadyTethering()3354     public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
3355         WifiConfiguration config = createValidWifiApConfiguration();
3356         mLooper.startAutoDispatch();
3357         assertTrue(mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME));
3358         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3359         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
3360         mLooper.stopAutoDispatchAndIgnoreExceptions();
3361 
3362         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
3363         when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
3364         mLooper.dispatchAll();
3365         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
3366                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3367         assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode);
3368     }
3369 
3370     /**
3371      * Only start LocalOnlyHotspot if admin setting does not disallow tethering.
3372      */
3373     @Test
testHotspotDoesNotStartWhenTetheringDisallowed()3374     public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
3375         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
3376         when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
3377         when(mUserManager.hasUserRestrictionForUser(
3378                 eq(UserManager.DISALLOW_CONFIG_TETHERING), any()))
3379                 .thenReturn(true);
3380         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
3381                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3382         assertEquals(ERROR_TETHERING_DISALLOWED, returnCode);
3383     }
3384 
3385     /**
3386      * Verify that callers can only have one registered LOHS request.
3387      */
3388     @Test(expected = IllegalStateException.class)
testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered()3389     public void testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered() {
3390         mLooper.startAutoDispatch();
3391         registerLOHSRequestFull();
3392         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3393 
3394         // now do the second request that will fail
3395         mWifiServiceImpl.startLocalOnlyHotspot(
3396                 mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
3397     }
3398 
3399     /**
3400      * Verify that the call to stopLocalOnlyHotspot does not do anything when there aren't any
3401      * registered callers.
3402      */
3403     @Test
testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests()3404     public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() throws Exception {
3405         // allow test to proceed without a permission check failure
3406         mWifiServiceImpl.stopLocalOnlyHotspot();
3407         mLooper.dispatchAll();
3408         // there is nothing registered, so this shouldn't do anything
3409         verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
3410     }
3411 
3412     /**
3413      * Verify that the call to stopLocalOnlyHotspot does not do anything when one caller unregisters
3414      * but there is still an active request
3415      */
3416     @Test
testStopLocalOnlyHotspotDoesNothingWithRemainingRequest()3417     public void testStopLocalOnlyHotspotDoesNothingWithRemainingRequest() throws Exception {
3418         mLooper.startAutoDispatch();
3419         // register a request that will remain after the stopLOHS call
3420         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
3421 
3422         setupLocalOnlyHotspot();
3423         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3424         // Since we are calling with the same pid, the second register call will be removed
3425         mWifiServiceImpl.stopLocalOnlyHotspot();
3426         mLooper.dispatchAll();
3427         // there is still a valid registered request - do not tear down LOHS
3428         verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
3429     }
3430 
3431     /**
3432      * Verify that the call to stopLocalOnlyHotspot sends a message to WifiController to stop
3433      * the softAp when there is one registered caller when that caller is removed.
3434      */
3435     @Test
testStopLocalOnlyHotspotTriggersStopWithOneRegisteredRequest()3436     public void testStopLocalOnlyHotspotTriggersStopWithOneRegisteredRequest() throws Exception {
3437         setupLocalOnlyHotspot();
3438 
3439         verify(mActiveModeWarden).startSoftAp(any(), any());
3440 
3441         mWifiServiceImpl.stopLocalOnlyHotspot();
3442         mLooper.dispatchAll();
3443 
3444         // No permission check required for change_wifi_state.
3445         verify(mContext, never()).enforceCallingOrSelfPermission(
3446                 eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString());
3447 
3448         // there is was only one request registered, we should tear down LOHS
3449         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
3450     }
3451 
3452     /**
3453      * Verify that by default startLocalOnlyHotspot starts access point at 2 GHz.
3454      */
3455     @Test
testStartLocalOnlyHotspotAt2Ghz()3456     public void testStartLocalOnlyHotspotAt2Ghz() {
3457         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
3458         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
3459                 eq(mContext), eq(null), any())).thenReturn(lohsConfig);
3460         mLooper.startAutoDispatch();
3461         registerLOHSRequestFull();
3462         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3463         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
3464                 eq(mContext), eq(null), any());
3465         verifyLohsBand(SoftApConfiguration.BAND_2GHZ);
3466     }
3467 
verifyLohsBand(int expectedBand)3468     private void verifyLohsBand(int expectedBand) {
3469         verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
3470                 eq(TEST_SETTINGS_WORKSOURCE));
3471         final SoftApConfiguration configuration =
3472                 mSoftApModeConfigCaptor.getValue().getSoftApConfiguration();
3473         assertNotNull(configuration);
3474         assertEquals(expectedBand, configuration.getBand());
3475     }
3476 
3477     private static class FakeLohsCallback extends ILocalOnlyHotspotCallback.Stub {
3478         boolean mIsStarted = false;
3479         SoftApConfiguration mSoftApConfig = null;
3480 
3481         @Override
onHotspotStarted(SoftApConfiguration softApConfig)3482         public void onHotspotStarted(SoftApConfiguration softApConfig) {
3483             mIsStarted = true;
3484             this.mSoftApConfig = softApConfig;
3485         }
3486 
3487         @Override
onHotspotStopped()3488         public void onHotspotStopped() {
3489             mIsStarted = false;
3490             mSoftApConfig = null;
3491         }
3492 
3493         @Override
onHotspotFailed(int i)3494         public void onHotspotFailed(int i) {
3495             mIsStarted = false;
3496             mSoftApConfig = null;
3497         }
3498     }
3499 
setupForCustomLohs()3500     private void setupForCustomLohs() {
3501         setupLohsPermissions();
3502         when(mContext.checkPermission(eq(Manifest.permission.NETWORK_SETUP_WIZARD),
3503                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3504         setupWardenForCustomLohs();
3505     }
3506 
setupWardenForCustomLohs()3507     private void setupWardenForCustomLohs() {
3508         doAnswer(invocation -> {
3509             changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
3510             mWifiServiceImpl.updateInterfaceIpState(mLohsInterfaceName, IFACE_IP_MODE_LOCAL_ONLY);
3511             return null;
3512         }).when(mActiveModeWarden).startSoftAp(any(), any());
3513     }
3514 
3515     @Test(expected = SecurityException.class)
testCustomLohs_FailsWithoutPermission()3516     public void testCustomLohs_FailsWithoutPermission() {
3517         SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
3518                 .setSsid("customConfig")
3519                 .build();
3520         // set up basic permissions, but not NETWORK_SETUP_WIZARD
3521         setupLohsPermissions();
3522         setupWardenForCustomLohs();
3523         mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
3524                 customConfig, mExtras);
3525     }
3526 
nopDeathCallback(LocalOnlyHotspotRequestInfo requestor)3527     private static void nopDeathCallback(LocalOnlyHotspotRequestInfo requestor) {
3528     }
3529 
3530     @Test
testCustomLohs_ExclusiveAfterShared()3531     public void testCustomLohs_ExclusiveAfterShared() {
3532         mLooper.startAutoDispatch();
3533         FakeLohsCallback sharedCallback = new FakeLohsCallback();
3534         FakeLohsCallback exclusiveCallback = new FakeLohsCallback();
3535         SoftApConfiguration exclusiveConfig = new SoftApConfiguration.Builder()
3536                 .setSsid("customSsid")
3537                 .build();
3538 
3539         setupForCustomLohs();
3540         mWifiServiceImpl.registerLOHSForTest(mPid,
3541                 new LocalOnlyHotspotRequestInfo(mLooper.getLooper(), new WorkSource(),
3542                         sharedCallback, WifiServiceImplTest::nopDeathCallback, null));
3543         assertThat(mWifiServiceImpl.startLocalOnlyHotspot(exclusiveCallback, TEST_PACKAGE_NAME,
3544                 TEST_FEATURE_ID, exclusiveConfig, mExtras)).isEqualTo(ERROR_GENERIC);
3545         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3546         assertThat(sharedCallback.mIsStarted).isTrue();
3547         assertThat(exclusiveCallback.mIsStarted).isFalse();
3548     }
3549 
3550     @Test
testCustomLohs_ExclusiveBeforeShared()3551     public void testCustomLohs_ExclusiveBeforeShared() {
3552         mLooper.startAutoDispatch();
3553         FakeLohsCallback sharedCallback = new FakeLohsCallback();
3554         FakeLohsCallback exclusiveCallback = new FakeLohsCallback();
3555         SoftApConfiguration exclusiveConfig = new SoftApConfiguration.Builder()
3556                 .setSsid("customSsid")
3557                 .build();
3558 
3559         setupForCustomLohs();
3560         mWifiServiceImpl.registerLOHSForTest(mPid,
3561                 new LocalOnlyHotspotRequestInfo(mLooper.getLooper(), new WorkSource(),
3562                         exclusiveCallback, WifiServiceImplTest::nopDeathCallback, exclusiveConfig));
3563         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3564         assertThat(mWifiServiceImpl.startLocalOnlyHotspot(sharedCallback, TEST_PACKAGE_NAME,
3565                 TEST_FEATURE_ID, null, mExtras)).isEqualTo(ERROR_GENERIC);
3566         assertThat(exclusiveCallback.mIsStarted).isTrue();
3567         assertThat(sharedCallback.mIsStarted).isFalse();
3568     }
3569 
3570     @Test
testCustomLohs_Wpa2()3571     public void testCustomLohs_Wpa2() {
3572         SoftApConfiguration config = new SoftApConfiguration.Builder()
3573                 .setSsid("customSsid")
3574                 .setPassphrase("passphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
3575                 .build();
3576         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
3577                 eq(mContext), eq(config), any())).thenReturn(config);
3578         FakeLohsCallback callback = new FakeLohsCallback();
3579         mLooper.startAutoDispatch();
3580         setupForCustomLohs();
3581         assertThat(
3582                 mWifiServiceImpl.startLocalOnlyHotspot(callback, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
3583                         config, mExtras)).isEqualTo(REQUEST_REGISTERED);
3584         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3585         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
3586                 eq(mContext), eq(config), any());
3587         // Use app's worksouce.
3588         verify(mActiveModeWarden).startSoftAp(any(),
3589                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3590         assertThat(callback.mIsStarted).isTrue();
3591         assertThat(callback.mSoftApConfig.getWifiSsid().getUtf8Text()).isEqualTo("customSsid");
3592         assertThat(callback.mSoftApConfig.getSecurityType())
3593                 .isEqualTo(SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
3594         assertThat(callback.mSoftApConfig.getPassphrase()).isEqualTo("passphrase");
3595     }
3596 
3597     @Test
testCustomLohs_Open()3598     public void testCustomLohs_Open() {
3599         SoftApConfiguration config = new SoftApConfiguration.Builder()
3600                 .setSsid("customSsid")
3601                 .build();
3602         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
3603                 eq(mContext), eq(config), any())).thenReturn(config);
3604         FakeLohsCallback callback = new FakeLohsCallback();
3605         mLooper.startAutoDispatch();
3606         setupForCustomLohs();
3607         assertThat(
3608                 mWifiServiceImpl.startLocalOnlyHotspot(callback, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
3609                         config, mExtras)).isEqualTo(REQUEST_REGISTERED);
3610         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3611         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
3612                 eq(mContext), eq(config), any());
3613         // Use app's worksouce.
3614         verify(mActiveModeWarden).startSoftAp(any(),
3615                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3616         assertThat(callback.mIsStarted).isTrue();
3617         assertThat(callback.mSoftApConfig.getWifiSsid().getUtf8Text()).isEqualTo("customSsid");
3618         assertThat(callback.mSoftApConfig.getSecurityType())
3619                 .isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN);
3620         assertThat(callback.mSoftApConfig.getPassphrase()).isNull();
3621     }
3622 
3623     @Test
testCustomLohs_GeneratesSsidIfAbsent()3624     public void testCustomLohs_GeneratesSsidIfAbsent() {
3625         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
3626         SoftApConfiguration customizedConfig = new SoftApConfiguration.Builder()
3627                 .setPassphrase("passphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
3628                 .build();
3629         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
3630                 eq(mContext), eq(customizedConfig), any()))
3631                 .thenReturn(lohsConfig);
3632         mLooper.startAutoDispatch();
3633         FakeLohsCallback callback = new FakeLohsCallback();
3634 
3635         setupForCustomLohs();
3636         assertThat(
3637                 mWifiServiceImpl.startLocalOnlyHotspot(callback, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
3638                         customizedConfig, mExtras)).isEqualTo(REQUEST_REGISTERED);
3639         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3640         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
3641                 eq(mContext), eq(customizedConfig), any());
3642         // Use app's worksouce.
3643         verify(mActiveModeWarden).startSoftAp(any(),
3644                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3645         assertThat(callback.mIsStarted).isTrue();
3646         assertThat(callback.mSoftApConfig.getWifiSsid()).isNotNull();
3647     }
3648 
3649     @Test
testCustomLohs_ForwardsBssid()3650     public void testCustomLohs_ForwardsBssid() {
3651         mLooper.startAutoDispatch();
3652         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
3653         SoftApConfiguration.Builder customizedConfigBuilder =
3654                 new SoftApConfiguration.Builder(lohsConfig)
3655                 .setBssid(MacAddress.fromString("aa:bb:cc:dd:ee:ff"));
3656         if (SdkLevel.isAtLeastS()) {
3657             customizedConfigBuilder.setMacRandomizationSetting(
3658                     SoftApConfiguration.RANDOMIZATION_NONE);
3659         }
3660         SoftApConfiguration customizedConfig = customizedConfigBuilder.build();
3661         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
3662                 eq(mContext), eq(customizedConfig), any()))
3663                 .thenReturn(customizedConfig);
3664         FakeLohsCallback callback = new FakeLohsCallback();
3665 
3666         setupForCustomLohs();
3667         assertThat(
3668                 mWifiServiceImpl.startLocalOnlyHotspot(callback, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
3669                         customizedConfig, mExtras)).isEqualTo(REQUEST_REGISTERED);
3670         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3671 
3672         // Use app's worksouce.
3673         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
3674                 eq(mContext), eq(customizedConfig), any());
3675         verify(mActiveModeWarden).startSoftAp(any(),
3676                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
3677         assertThat(callback.mIsStarted).isTrue();
3678         assertThat(callback.mSoftApConfig.getBssid().toString())
3679                 .ignoringCase().isEqualTo("aa:bb:cc:dd:ee:ff");
3680     }
3681 
3682     /**
3683          * Verify that WifiServiceImpl does not send the stop ap message if there were no
3684          * pending LOHS requests upon a binder death callback.
3685          */
3686     @Test
testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests()3687     public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() {
3688         LocalOnlyRequestorCallback binderDeathCallback =
3689                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
3690 
3691         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
3692         verify(mActiveModeWarden, never()).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
3693     }
3694 
3695     /**
3696      * Verify that WifiServiceImpl does not send the stop ap message if there are remaining
3697      * registered LOHS requests upon a binder death callback.  Additionally verify that softap mode
3698      * will be stopped if that remaining request is removed (to verify the binder death properly
3699      * cleared the requestor that died).
3700      */
3701     @Test
testServiceImplNotCalledWhenBinderDeathTriggeredWithRequests()3702     public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRequests() throws Exception {
3703         mLooper.startAutoDispatch();
3704         LocalOnlyRequestorCallback binderDeathCallback =
3705                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
3706 
3707         // registering a request directly from the test will not trigger a message to start
3708         // softap mode
3709         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
3710 
3711         setupLocalOnlyHotspot();
3712 
3713         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
3714         verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
3715 
3716         reset(mActiveModeWarden);
3717 
3718         // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder
3719         // death requestor was removed
3720         mWifiServiceImpl.stopLocalOnlyHotspot();
3721         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
3722         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
3723     }
3724 
3725     /**
3726      * Verify that a call to registerSoftApCallback throws a SecurityException if the caller does
3727      * not have neither NETWORK_SETTINGS nor MAINLINE_NETWORK_STACK permission.
3728      */
3729     @Test(expected = SecurityException.class)
registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions()3730     public void registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
3731         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3732                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
3733         when(mContext.checkPermission(eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK),
3734                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
3735         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
3736         mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
3737     }
3738 
3739     /**
3740      * Verify that a call to registerSoftApCallback throws an IllegalArgumentException if the
3741      * parameters are not provided.
3742      */
3743     @Test
registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()3744     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
3745         try {
3746             mWifiServiceImpl.registerSoftApCallback(null);
3747             fail("expected IllegalArgumentException");
3748         } catch (IllegalArgumentException expected) {
3749         }
3750     }
3751 
3752     /**
3753      * Verify that a call to unregisterSoftApCallback throws a SecurityException if the caller does
3754      * not have neither NETWORK_SETTINGS nor MAINLINE_NETWORK_STACK permission.
3755      */
3756     @Test(expected = SecurityException.class)
unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions()3757     public void unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
3758         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3759                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
3760         when(mContext.checkPermission(eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK),
3761                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
3762         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
3763         mWifiServiceImpl.unregisterSoftApCallback(mClientSoftApCallback);
3764     }
3765 
3766     /**
3767      * Verifies that we handle softap callback registration failure if we encounter an exception
3768      * while linking to death.
3769      */
3770     @Test
registerSoftApCallbackFailureOnLinkToDeath()3771     public void registerSoftApCallbackFailureOnLinkToDeath() throws Exception {
3772         doThrow(new RemoteException())
3773                 .when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
3774         mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
3775         mLooper.dispatchAll();
3776         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
3777         verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
3778                 any(), any(), anyBoolean(), anyBoolean());
3779         verify(mClientSoftApCallback, never()).onCapabilityChanged(any());
3780     }
3781 
3782     /**
3783      * Registers a soft AP callback, then verifies that the current soft AP state and num clients
3784      * are sent to caller immediately after callback is registered.
3785      */
registerSoftApCallbackAndVerify(ISoftApCallback callback)3786     private void registerSoftApCallbackAndVerify(ISoftApCallback callback) throws Exception {
3787         mWifiServiceImpl.registerSoftApCallback(callback);
3788         mLooper.dispatchAll();
3789         verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
3790         verify(callback).onConnectedClientsOrInfoChanged(new HashMap<String, SoftApInfo>(),
3791                 new HashMap<String, List<WifiClient>>(), false, true);
3792         verify(callback).onCapabilityChanged(ApConfigUtil.updateCapabilityFromResource(mContext));
3793         // Don't need to invoke callback when register.
3794         verify(callback, never()).onBlockedClientConnecting(any(), anyInt());
3795     }
3796 
3797     /**
3798      * Verify that unregisterSoftApCallback removes callback from registered callbacks list
3799      */
3800     @Test
unregisterSoftApCallbackRemovesCallback()3801     public void unregisterSoftApCallbackRemovesCallback() throws Exception {
3802         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3803 
3804         mWifiServiceImpl.unregisterSoftApCallback(mClientSoftApCallback);
3805         mLooper.dispatchAll();
3806 
3807         reset(mClientSoftApCallback);
3808         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3809                 mTestSoftApInfos, mTestSoftApClients, false);
3810         mLooper.dispatchAll();
3811         verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
3812                 any(), any(), anyBoolean(), anyBoolean());
3813     }
3814 
3815     /**
3816      * Verify that unregisterSoftApCallback is no-op if callback not registered.
3817      */
3818     @Test
unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackNotMatching()3819     public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackNotMatching()
3820             throws Exception {
3821         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3822 
3823         mWifiServiceImpl.unregisterSoftApCallback(mAnotherSoftApCallback);
3824         mLooper.dispatchAll();
3825         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3826                 mTestSoftApInfos, mTestSoftApClients, false);
3827         mLooper.dispatchAll();
3828         verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
3829                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(false));
3830     }
3831 
3832     /**
3833      * Registers two callbacks, remove one then verify the right callback is being called on events.
3834      */
3835     @Test
correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne()3836     public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception {
3837         WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"),
3838                 WIFI_IFACE_NAME2);
3839         mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
3840         mLooper.dispatchAll();
3841 
3842         reset(mClientSoftApCallback);
3843         when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
3844         // Change state from default before registering the second callback
3845         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3846         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3847                 mTestSoftApInfos, mTestSoftApClients, false);
3848         mStateMachineSoftApCallback.onBlockedClientConnecting(testWifiClient, 0);
3849 
3850 
3851         // Register another callback and verify the new state is returned in the immediate callback
3852         mWifiServiceImpl.registerSoftApCallback(mAnotherSoftApCallback);
3853         mLooper.dispatchAll();
3854         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3855         verify(mAnotherSoftApCallback).onConnectedClientsOrInfoChanged(
3856                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
3857         // Verify only first callback will receive onBlockedClientConnecting since it call after
3858         // first callback register but before another callback register.
3859         verify(mClientSoftApCallback).onBlockedClientConnecting(testWifiClient, 0);
3860         verify(mAnotherSoftApCallback, never()).onBlockedClientConnecting(testWifiClient, 0);
3861 
3862         // unregister the fisrt callback
3863         mWifiServiceImpl.unregisterSoftApCallback(mClientSoftApCallback);
3864         mLooper.dispatchAll();
3865 
3866         // Update soft AP state and verify the remaining callback receives the event
3867         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
3868                 SAP_START_FAILURE_NO_CHANNEL);
3869         mLooper.dispatchAll();
3870         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
3871                 SAP_START_FAILURE_NO_CHANNEL);
3872         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
3873                 SAP_START_FAILURE_NO_CHANNEL);
3874     }
3875 
3876     /**
3877      * Verify that wifi service registers for callers BinderDeath event
3878      */
3879     @Test
registersForBinderDeathOnRegisterSoftApCallback()3880     public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception {
3881         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3882         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
3883     }
3884 
3885     /**
3886      * Verify that we un-register the soft AP callback on receiving BinderDied event.
3887      */
3888     @Test
unregistersSoftApCallbackOnBinderDied()3889     public void unregistersSoftApCallbackOnBinderDied() throws Exception {
3890         ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
3891                 ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
3892         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3893         verify(mAppBinder).linkToDeath(drCaptor.capture(), anyInt());
3894 
3895         drCaptor.getValue().binderDied();
3896         mLooper.dispatchAll();
3897         reset(mClientSoftApCallback);
3898         // Verify callback is removed from the list as well
3899         Map<String, List<WifiClient>> mTestSoftApClients = mock(Map.class);
3900         Map<String, SoftApInfo> mTestSoftApInfos = mock(Map.class);
3901         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3902                 mTestSoftApInfos, mTestSoftApClients, false);
3903         mLooper.dispatchAll();
3904         verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
3905                 any(), any(), anyBoolean(), anyBoolean());
3906     }
3907 
3908     /**
3909      * Verify that soft AP callback is called on NumClientsChanged event
3910      */
3911     @Test
callsRegisteredCallbacksOnConnectedClientsChangedEvent()3912     public void callsRegisteredCallbacksOnConnectedClientsChangedEvent() throws Exception {
3913         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3914 
3915         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3916                 mTestSoftApInfos, mTestSoftApClients, false);
3917         mLooper.dispatchAll();
3918         verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
3919                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(false));
3920     }
3921 
3922     /**
3923      * Verify that soft AP callback is called on SoftApStateChanged event
3924      */
3925     @Test
callsRegisteredCallbacksOnSoftApStateChangedEvent()3926     public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception {
3927         registerSoftApCallbackAndVerify(mClientSoftApCallback);
3928 
3929         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3930         mLooper.dispatchAll();
3931         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3932     }
3933 
3934     /**
3935      * Verify that mSoftApState and mSoftApNumClients in WifiServiceImpl are being updated on soft
3936      * Ap events, even when no callbacks are registered.
3937      */
3938     @Test
updatesSoftApStateAndConnectedClientsOnSoftApEvents()3939     public void updatesSoftApStateAndConnectedClientsOnSoftApEvents() throws Exception {
3940         WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"),
3941                 WIFI_IFACE_NAME2);
3942         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3943         mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
3944                 mTestSoftApInfos, mTestSoftApClients, false);
3945         mStateMachineSoftApCallback.onBlockedClientConnecting(testWifiClient, 0);
3946 
3947         // Register callback after num clients and soft AP are changed.
3948         mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
3949         mLooper.dispatchAll();
3950         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
3951         verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
3952                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
3953         // Don't need to invoke callback when register.
3954         verify(mClientSoftApCallback, never()).onBlockedClientConnecting(any(), anyInt());
3955     }
3956 
3957     private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
3958         @Override
matches(IntentFilter filter)3959         public boolean matches(IntentFilter filter) {
3960             return filter.hasAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
3961         }
3962     }
3963 
3964     /**
3965      * Verify that onFailed is called for registered LOHS callers on SAP_START_FAILURE_GENERAL.
3966      */
3967     @Test
testRegisteredCallbacksTriggeredOnSoftApFailureGeneric()3968     public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception {
3969         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
3970         mWifiServiceImpl.checkAndStartWifi();
3971         mLooper.dispatchAll();
3972 
3973         verifyApRegistration();
3974 
3975         registerLOHSRequestFull();
3976 
3977         changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL);
3978         mLooper.dispatchAll();
3979 
3980         verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
3981     }
3982 
3983     /**
3984      * Verify that onFailed is called for registered LOHS callers on SAP_START_FAILURE_NO_CHANNEL.
3985      */
3986     @Test
testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel()3987     public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception {
3988         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
3989         mWifiServiceImpl.checkAndStartWifi();
3990         mLooper.dispatchAll();
3991 
3992         verifyApRegistration();
3993 
3994         registerLOHSRequestFull();
3995 
3996         changeLohsState(WIFI_AP_STATE_FAILED,
3997                 WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL);
3998 
3999         mLooper.dispatchAll();
4000         verify(mLohsCallback).onHotspotFailed(ERROR_NO_CHANNEL);
4001     }
4002 
4003     /**
4004      * Common setup for starting a LOHS.
4005      */
setupLocalOnlyHotspot()4006     private void setupLocalOnlyHotspot() throws Exception {
4007         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4008         mWifiServiceImpl.checkAndStartWifi();
4009         mLooper.dispatchAll();
4010 
4011         verifyApRegistration();
4012 
4013         registerLOHSRequestFull();
4014 
4015         changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
4016         mWifiServiceImpl.updateInterfaceIpState(mLohsInterfaceName, IFACE_IP_MODE_LOCAL_ONLY);
4017         mLooper.dispatchAll();
4018         verify(mLohsCallback).onHotspotStarted(any());
4019     }
4020 
4021     /**
4022      * Verify that onStopped is called for registered LOHS callers when a callback is
4023      * received with WIFI_AP_STATE_DISABLING and LOHS was active.
4024      */
4025     @Test
testRegisteredCallbacksTriggeredOnSoftApDisabling()4026     public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception {
4027         setupLocalOnlyHotspot();
4028 
4029         changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
4030 
4031         mLooper.dispatchAll();
4032         verify(mLohsCallback).onHotspotStopped();
4033     }
4034 
4035 
4036     /**
4037      * Verify that onStopped is called for registered LOHS callers when a callback is
4038      * received with WIFI_AP_STATE_DISABLED and LOHS was enabled.
4039      */
4040     @Test
testRegisteredCallbacksTriggeredOnSoftApDisabled()4041     public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception {
4042         setupLocalOnlyHotspot();
4043 
4044         changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
4045 
4046         mLooper.dispatchAll();
4047         verify(mLohsCallback).onHotspotStopped();
4048     }
4049 
4050     /**
4051      * Verify that no callbacks are called for registered LOHS callers when a callback is
4052      * received and the softap started.
4053      */
4054     @Test
testRegisteredCallbacksNotTriggeredOnSoftApStart()4055     public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception {
4056         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4057         mWifiServiceImpl.checkAndStartWifi();
4058         mLooper.dispatchAll();
4059 
4060         verifyApRegistration();
4061 
4062         registerLOHSRequestFull();
4063 
4064         changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
4065 
4066         mLooper.dispatchAll();
4067         verifyZeroInteractions(ignoreStubs(mLohsCallback));
4068     }
4069 
4070     /**
4071      * Verify that onStopped is called only once for registered LOHS callers when
4072      * callbacks are received with WIFI_AP_STATE_DISABLING and
4073      * WIFI_AP_STATE_DISABLED when LOHS was enabled.
4074      */
4075     @Test
testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling()4076     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception {
4077         setupLocalOnlyHotspot();
4078 
4079         changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
4080         changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
4081 
4082         mLooper.dispatchAll();
4083         verify(mLohsCallback).onHotspotStopped();
4084     }
4085 
4086     /**
4087      * Verify that onFailed is called only once for registered LOHS callers when
4088      * callbacks are received with WIFI_AP_STATE_FAILED twice.
4089      */
4090     @Test
testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice()4091     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception {
4092         setupLocalOnlyHotspot();
4093 
4094         changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
4095         changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
4096 
4097         mLooper.dispatchAll();
4098         verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
4099     }
4100 
4101     /**
4102      * Verify that onFailed is called for all registered LOHS callers when
4103      * callbacks are received with WIFI_AP_STATE_FAILED.
4104      */
4105     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApFails()4106     public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception {
4107         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4108         mWifiServiceImpl.checkAndStartWifi();
4109         mLooper.dispatchAll();
4110 
4111         verifyApRegistration();
4112 
4113         // make an additional request for this test
4114         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4115 
4116         registerLOHSRequestFull();
4117 
4118         changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
4119         changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
4120 
4121         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
4122         mLooper.dispatchAll();
4123         verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
4124     }
4125 
4126     /**
4127      * Verify that onStopped is called for all registered LOHS callers when
4128      * callbacks are received with WIFI_AP_STATE_DISABLED when LOHS was
4129      * active.
4130      */
4131     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApStops()4132     public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception {
4133         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4134         mWifiServiceImpl.checkAndStartWifi();
4135         mLooper.dispatchAll();
4136 
4137         verifyApRegistration();
4138 
4139         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4140 
4141         registerLOHSRequestFull();
4142 
4143         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4144         mLooper.dispatchAll();
4145         verify(mRequestInfo).sendHotspotStartedMessage(any());
4146         verify(mLohsCallback).onHotspotStarted(any());
4147 
4148         reset(mRequestInfo);
4149         clearInvocations(mLohsCallback);
4150 
4151         changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
4152         changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
4153 
4154         verify(mRequestInfo).sendHotspotStoppedMessage();
4155         mLooper.dispatchAll();
4156         verify(mLohsCallback).onHotspotStopped();
4157     }
4158 
4159     /**
4160      * Verify that onFailed is called for all registered LOHS callers when
4161      * callbacks are received with WIFI_AP_STATE_DISABLED when LOHS was
4162      * not active.
4163      */
4164     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive()4165     public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception {
4166         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4167         mWifiServiceImpl.checkAndStartWifi();
4168         mLooper.dispatchAll();
4169 
4170         verifyApRegistration();
4171 
4172         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4173         mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2);
4174 
4175         changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
4176         changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
4177 
4178         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
4179         verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC);
4180     }
4181 
4182     /**
4183      * Verify that if we do not have registered LOHS requestors and we receive an update that LOHS
4184      * is up and ready for use, we tell WifiController to tear it down.  This can happen if softap
4185      * mode fails to come up properly and we get an onFailed message for a tethering call and we
4186      * had registered callers for LOHS.
4187      */
4188     @Test
testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode()4189     public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() {
4190         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4191         mLooper.dispatchAll();
4192 
4193         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
4194     }
4195 
4196     /**
4197      * Verify that all registered LOHS requestors are notified via a HOTSPOT_STARTED message that
4198      * the hotspot is up and ready to use.
4199      */
4200     @Test
testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()4201     public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()
4202             throws Exception {
4203         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
4204         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
4205                 eq(mContext), eq(null), any())).thenReturn(lohsConfig);
4206         mLooper.startAutoDispatch();
4207         registerLOHSRequestFull();
4208         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
4209         verify(mWifiApConfigStore).generateLocalOnlyHotspotConfig(
4210                 eq(mContext), eq(null), any());
4211         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4212 
4213         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4214         mLooper.dispatchAll();
4215         verify(mRequestInfo).sendHotspotStartedMessage(any(SoftApConfiguration.class));
4216 
4217         mLooper.dispatchAll();
4218         verify(mLohsCallback).onHotspotStarted(notNull());
4219     }
4220 
4221     /**
4222      * Verify that if a LOHS is already active, a new call to register a request will trigger the
4223      * onStarted callback.
4224      */
4225     @Test
testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()4226     public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()
4227             throws Exception {
4228         mLooper.startAutoDispatch();
4229         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4230 
4231         changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
4232         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4233 
4234         registerLOHSRequestFull();
4235         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
4236         verify(mLohsCallback).onHotspotStarted(any());
4237     }
4238 
4239     /**
4240      * Verify that if a LOHS request is active and we receive an update with an ip mode
4241      * configuration error, callers are notified via the onFailed callback with the generic
4242      * error and are unregistered.
4243      */
4244     @Test
testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails()4245     public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception {
4246         setupLocalOnlyHotspot();
4247         reset(mActiveModeWarden);
4248 
4249         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
4250         mLooper.dispatchAll();
4251 
4252         verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
4253         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
4254 
4255         clearInvocations(mLohsCallback);
4256 
4257         // send HOTSPOT_FAILED message should only happen once since the requestor should be
4258         // unregistered
4259         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
4260         mLooper.dispatchAll();
4261         verifyZeroInteractions(ignoreStubs(mLohsCallback));
4262     }
4263 
4264     /**
4265      * Verify that softap mode is stopped for tethering if we receive an update with an ip mode
4266      * configuration error.
4267      */
4268     @Test
testStopSoftApWhenIpConfigFails()4269     public void testStopSoftApWhenIpConfigFails() throws Exception {
4270         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
4271         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
4272         mLooper.dispatchAll();
4273 
4274         verify(mActiveModeWarden).stopSoftAp(IFACE_IP_MODE_TETHERED);
4275     }
4276 
4277     /**
4278      * Verify that if a LOHS request is active and tethering starts, callers are notified on the
4279      * incompatible mode and are unregistered.
4280      */
4281     @Test
testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts()4282     public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception {
4283         mLooper.startAutoDispatch();
4284         registerLOHSRequestFull();
4285 
4286         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4287         mLooper.dispatchAll();
4288         verify(mLohsCallback).onHotspotStarted(any());
4289         clearInvocations(mLohsCallback);
4290 
4291         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
4292         mLooper.dispatchAll();
4293 
4294         verify(mLohsCallback).onHotspotFailed(ERROR_INCOMPATIBLE_MODE);
4295 
4296         // sendMessage should only happen once since the requestor should be unregistered
4297         clearInvocations(mLohsCallback);
4298 
4299         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
4300         verifyZeroInteractions(ignoreStubs(mLohsCallback));
4301         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
4302     }
4303 
4304     /**
4305      * Verify that if LOHS is disabled, a new call to register a request will not trigger the
4306      * onStopped callback.
4307      */
4308     @Test
testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback()4309     public void testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback()
4310             throws Exception {
4311         mLooper.startAutoDispatch();
4312         registerLOHSRequestFull();
4313         verifyZeroInteractions(ignoreStubs(mLohsCallback));
4314         stopAutoDispatchWithDispatchAllBeforeStopAndIgnoreExceptions(mLooper);
4315     }
4316 
4317     /**
4318      * Verify that if a LOHS was active and then stopped, a new call to register a request will
4319      * not trigger the onStarted callback.
4320      */
4321     @Test
testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()4322     public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()
4323             throws Exception {
4324         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
4325         mWifiServiceImpl.checkAndStartWifi();
4326         mLooper.dispatchAll();
4327         verifyApRegistration();
4328 
4329         // register a request so we don't drop the LOHS interface ip update
4330         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
4331         changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
4332         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
4333         mLooper.dispatchAll();
4334 
4335         registerLOHSRequestFull();
4336         mLooper.dispatchAll();
4337 
4338         verify(mLohsCallback).onHotspotStarted(any());
4339 
4340         clearInvocations(mLohsCallback);
4341 
4342         // now stop the hotspot
4343         changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
4344         changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
4345         mLooper.dispatchAll();
4346         verify(mLohsCallback).onHotspotStopped();
4347 
4348         clearInvocations(mLohsCallback);
4349 
4350         // now register a new caller - they should not get the onStarted callback
4351         ILocalOnlyHotspotCallback callback2 = mock(ILocalOnlyHotspotCallback.class);
4352         when(callback2.asBinder()).thenReturn(mock(IBinder.class));
4353 
4354         int result = mWifiServiceImpl.startLocalOnlyHotspot(
4355                 callback2, TEST_PACKAGE_NAME, TEST_FEATURE_ID, null, mExtras);
4356         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
4357         mLooper.dispatchAll();
4358 
4359         verify(mLohsCallback, never()).onHotspotStarted(any());
4360     }
4361 
4362     /**
4363      * Verify that a call to startWatchLocalOnlyHotspot is only allowed from callers with the
4364      * signature only NETWORK_SETTINGS permission.
4365      *
4366      * This test is expecting the permission check to enforce the permission and throw a
4367      * SecurityException for callers without the permission.  This exception should be bubbled up to
4368      * the caller of startLocalOnlyHotspot.
4369      */
4370     @Test(expected = SecurityException.class)
testStartWatchLocalOnlyHotspotNotApprovedCaller()4371     public void testStartWatchLocalOnlyHotspotNotApprovedCaller() {
4372         doThrow(new SecurityException()).when(mContext)
4373                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4374                                                 eq("WifiService"));
4375         mWifiServiceImpl.startWatchLocalOnlyHotspot(mLohsCallback);
4376     }
4377 
4378     /**
4379      * Verify that the call to startWatchLocalOnlyHotspot throws the UnsupportedOperationException
4380      * when called until the implementation is complete.
4381      */
4382     @Test(expected = UnsupportedOperationException.class)
testStartWatchLocalOnlyHotspotNotSupported()4383     public void testStartWatchLocalOnlyHotspotNotSupported() {
4384         mWifiServiceImpl.startWatchLocalOnlyHotspot(mLohsCallback);
4385     }
4386 
4387     /**
4388      * Verify that a call to stopWatchLocalOnlyHotspot is only allowed from callers with the
4389      * signature only NETWORK_SETTINGS permission.
4390      */
4391     @Test(expected = SecurityException.class)
testStopWatchLocalOnlyHotspotNotApprovedCaller()4392     public void testStopWatchLocalOnlyHotspotNotApprovedCaller() {
4393         doThrow(new SecurityException()).when(mContext)
4394                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4395                                                 eq("WifiService"));
4396         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
4397     }
4398 
4399     /**
4400      * Verify that the call to stopWatchLocalOnlyHotspot throws the UnsupportedOperationException
4401      * until the implementation is complete.
4402      */
4403     @Test(expected = UnsupportedOperationException.class)
testStopWatchLocalOnlyHotspotNotSupported()4404     public void testStopWatchLocalOnlyHotspotNotSupported() {
4405         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
4406     }
4407 
4408     /**
4409      * Verify that the call to addOrUpdateNetwork for installing Passpoint profile is redirected
4410      * to the Passpoint specific API addOrUpdatePasspointConfiguration.
4411      */
4412     @Test
testAddPasspointProfileViaAddNetwork()4413     public void testAddPasspointProfileViaAddNetwork() throws Exception {
4414         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
4415         config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
4416 
4417         PackageManager pm = mock(PackageManager.class);
4418         when(mContext.getPackageManager()).thenReturn(pm);
4419         when(pm.getApplicationInfoAsUser(any(), anyInt(), any())).thenReturn(mApplicationInfo);
4420         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
4421                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
4422         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
4423                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(true);
4424 
4425         when(mPasspointManager.addOrUpdateProvider(
4426                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), eq(false),
4427                 eq(true))).thenReturn(true);
4428         mLooper.startAutoDispatch();
4429         assertEquals(0,
4430                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
4431         mLooper.stopAutoDispatchAndIgnoreExceptions();
4432         verifyCheckChangePermission(TEST_PACKAGE_NAME);
4433         verify(mPasspointManager).addOrUpdateProvider(
4434                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), eq(false),
4435                 eq(true));
4436         reset(mPasspointManager);
4437 
4438         when(mPasspointManager.addOrUpdateProvider(
4439                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), anyBoolean(),
4440                 anyBoolean())).thenReturn(false);
4441         mLooper.startAutoDispatch();
4442         assertEquals(-1,
4443                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
4444         mLooper.stopAutoDispatchAndIgnoreExceptions();
4445         verifyCheckChangePermission(TEST_PACKAGE_NAME);
4446         verify(mPasspointManager).addOrUpdateProvider(
4447                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), anyBoolean(),
4448                 anyBoolean());
4449     }
4450 
4451     /**
4452      * Verify that the call to getAllMatchingPasspointProfilesForScanResults is not redirected to
4453      * specific API getAllMatchingPasspointProfilesForScanResults when the caller doesn't have
4454      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
4455      */
4456     @Test(expected = SecurityException.class)
testGetAllMatchingPasspointProfilesForScanResultsWithoutPermissions()4457     public void testGetAllMatchingPasspointProfilesForScanResultsWithoutPermissions() {
4458         mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(new ArrayList<>());
4459     }
4460 
4461     /**
4462      * Verify that the call to getAllMatchingPasspointProfilesForScanResults is redirected to
4463      * specific API getAllMatchingPasspointProfilesForScanResults when the caller have
4464      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
4465      */
4466     @Test
testGetAllMatchingPasspointProfilesForScanResultsWithPermissions()4467     public void testGetAllMatchingPasspointProfilesForScanResultsWithPermissions() {
4468         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4469                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4470         mLooper.startAutoDispatch();
4471         mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(createScanResultList());
4472         mLooper.stopAutoDispatchAndIgnoreExceptions();
4473         verify(mPasspointManager).getAllMatchingPasspointProfilesForScanResults(any());
4474     }
4475 
4476     /**
4477      * Verify that the call to getAllMatchingPasspointProfilesForScanResults is not redirected to
4478      * specific API getAllMatchingPasspointProfilesForScanResults when the caller provider invalid
4479      * ScanResult.
4480      */
4481     @Test
testGetAllMatchingPasspointProfilesForScanResultsWithInvalidScanResult()4482     public void testGetAllMatchingPasspointProfilesForScanResultsWithInvalidScanResult() {
4483         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4484                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4485         mLooper.startAutoDispatch();
4486         mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(new ArrayList<>());
4487         mLooper.stopAutoDispatchAndIgnoreExceptions();
4488         verify(mPasspointManager, never()).getAllMatchingPasspointProfilesForScanResults(any());
4489     }
4490 
4491     /**
4492      * Verify that the call to getWifiConfigsForPasspointProfiles is not redirected to specific API
4493      * syncGetWifiConfigsForPasspointProfiles when the caller doesn't have NETWORK_SETTINGS
4494      * permissions and NETWORK_SETUP_WIZARD.
4495      */
4496     @Test(expected = SecurityException.class)
testGetWifiConfigsForPasspointProfilesWithoutPermissions()4497     public void testGetWifiConfigsForPasspointProfilesWithoutPermissions() {
4498         mWifiServiceImpl.getWifiConfigsForPasspointProfiles(new ArrayList<>());
4499     }
4500 
4501     /**
4502      * Verify that the call to getMatchingOsuProviders is not redirected to specific API
4503      * syncGetMatchingOsuProviders when the caller doesn't have NETWORK_SETTINGS
4504      * permissions and NETWORK_SETUP_WIZARD.
4505      */
4506     @Test(expected = SecurityException.class)
testGetMatchingOsuProvidersWithoutPermissions()4507     public void testGetMatchingOsuProvidersWithoutPermissions() {
4508         mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
4509     }
4510 
4511     /**
4512      * Verify that the call to getMatchingOsuProviders is redirected to specific API
4513      * syncGetMatchingOsuProviders when the caller have NETWORK_SETTINGS
4514      * permissions and NETWORK_SETUP_WIZARD.
4515      */
4516     @Test
testGetMatchingOsuProvidersWithPermissions()4517     public void testGetMatchingOsuProvidersWithPermissions() {
4518         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4519                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4520         mLooper.startAutoDispatch();
4521         mWifiServiceImpl.getMatchingOsuProviders(createScanResultList());
4522         mLooper.stopAutoDispatch();
4523         verify(mPasspointManager).getMatchingOsuProviders(any());
4524     }
4525 
4526     /**
4527      * Verify that the call to getMatchingOsuProviders is not redirected to specific API
4528      * syncGetMatchingOsuProviders when the caller provider invalid ScanResult
4529      */
4530     @Test
testGetMatchingOsuProvidersWithInvalidScanResult()4531     public void testGetMatchingOsuProvidersWithInvalidScanResult() {
4532         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4533                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4534         mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
4535         mLooper.dispatchAll();
4536         verify(mPasspointManager, never()).getMatchingOsuProviders(any());
4537     }
4538 
4539     /**
4540      * Verify that the call to getMatchingPasspointConfigsForOsuProviders is not redirected to
4541      * specific API syncGetMatchingPasspointConfigsForOsuProviders when the caller doesn't have
4542      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
4543      */
4544     @Test(expected = SecurityException.class)
testGetMatchingPasspointConfigsForOsuProvidersWithoutPermissions()4545     public void testGetMatchingPasspointConfigsForOsuProvidersWithoutPermissions() {
4546         mWifiServiceImpl.getMatchingPasspointConfigsForOsuProviders(new ArrayList<>());
4547     }
4548 
4549     /**
4550      * Verify that the call to startSubscriptionProvisioning is redirected to the Passpoint
4551      * specific API startSubscriptionProvisioning when the caller has the right permissions.
4552      */
4553     @Test
testStartSubscriptionProvisioningWithPermission()4554     public void testStartSubscriptionProvisioningWithPermission() throws Exception {
4555         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4556                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4557         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
4558                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4559 
4560         mLooper.startAutoDispatch();
4561         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
4562         mLooper.stopAutoDispatch();
4563         verify(mClientModeManager).syncStartSubscriptionProvisioning(anyInt(),
4564                 eq(mOsuProvider), eq(mProvisioningCallback));
4565     }
4566 
4567     /**
4568      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
4569      * specific API startSubscriptionProvisioning when the caller provides invalid arguments
4570      */
4571     @Test(expected = IllegalArgumentException.class)
testStartSubscriptionProvisioningWithInvalidProvider()4572     public void testStartSubscriptionProvisioningWithInvalidProvider() throws Exception {
4573         mWifiServiceImpl.startSubscriptionProvisioning(null, mProvisioningCallback);
4574     }
4575 
4576 
4577     /**
4578      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
4579      * specific API startSubscriptionProvisioning when the caller provides invalid callback
4580      */
4581     @Test(expected = IllegalArgumentException.class)
testStartSubscriptionProvisioningWithInvalidCallback()4582     public void testStartSubscriptionProvisioningWithInvalidCallback() throws Exception {
4583         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, null);
4584     }
4585 
4586     /**
4587      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
4588      * specific API startSubscriptionProvisioning when the caller doesn't have NETWORK_SETTINGS
4589      * permissions and NETWORK_SETUP_WIZARD.
4590      */
4591     @Test(expected = SecurityException.class)
testStartSubscriptionProvisioningWithoutPermissions()4592     public void testStartSubscriptionProvisioningWithoutPermissions() throws Exception {
4593         when(mContext.checkCallingOrSelfPermission(
4594                 eq(android.Manifest.permission.NETWORK_SETTINGS))).thenReturn(
4595                 PackageManager.PERMISSION_DENIED);
4596         when(mContext.checkSelfPermission(
4597                 eq(android.Manifest.permission.NETWORK_SETUP_WIZARD))).thenReturn(
4598                 PackageManager.PERMISSION_DENIED);
4599 
4600         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
4601     }
4602 
4603     /**
4604      * Verify the call to getPasspointConfigurations when the caller doesn't have
4605      * NETWORK_SETTINGS and NETWORK_SETUP_WIZARD permissions.
4606      */
4607     @Test
testGetPasspointConfigurationsWithOutPrivilegedPermissions()4608     public void testGetPasspointConfigurationsWithOutPrivilegedPermissions() {
4609         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
4610         when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
4611 
4612         mLooper.startAutoDispatch();
4613         mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
4614         mLooper.stopAutoDispatchAndIgnoreExceptions();
4615         verify(mPasspointManager).getProviderConfigs(Binder.getCallingUid(), false);
4616     }
4617 
4618     /**
4619      * Verify that the call to getPasspointConfigurations when the caller does have
4620      * NETWORK_SETTINGS permission.
4621      */
4622     @Test
testGetPasspointConfigurationsWithPrivilegedPermissions()4623     public void testGetPasspointConfigurationsWithPrivilegedPermissions() {
4624         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
4625 
4626         mLooper.startAutoDispatch();
4627         mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
4628         mLooper.stopAutoDispatchAndIgnoreExceptions();
4629         verify(mPasspointManager).getProviderConfigs(Binder.getCallingUid(), true);
4630     }
4631 
4632     /**
4633      * Verify that GetPasspointConfigurations will redirect calls to {@link PasspointManager}
4634      * and returning the result that's returned from {@link PasspointManager}.
4635      */
4636     @Test
testGetPasspointConfigurations()4637     public void testGetPasspointConfigurations() throws Exception {
4638         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
4639 
4640         // Setup expected configs.
4641         List<PasspointConfiguration> expectedConfigs = new ArrayList<>();
4642         PasspointConfiguration config = new PasspointConfiguration();
4643         HomeSp homeSp = new HomeSp();
4644         homeSp.setFqdn("test.com");
4645         config.setHomeSp(homeSp);
4646         expectedConfigs.add(config);
4647 
4648         when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
4649                 .thenReturn(expectedConfigs);
4650         mLooper.startAutoDispatch();
4651         assertEquals(expectedConfigs, mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE));
4652         mLooper.stopAutoDispatchAndIgnoreExceptions();
4653         reset(mPasspointManager);
4654 
4655         when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
4656                 .thenReturn(new ArrayList<PasspointConfiguration>());
4657         mLooper.startAutoDispatch();
4658         assertTrue(mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE).isEmpty());
4659         mLooper.stopAutoDispatchAndIgnoreExceptions();
4660     }
4661 
4662     /**
4663      * Verify the call to removePasspointConfigurations when the caller doesn't have
4664      * NETWORK_SETTINGS and NETWORK_CARRIER_PROVISIONING permissions.
4665      */
4666     @Test
testRemovePasspointConfigurationWithOutPrivilegedPermissions()4667     public void testRemovePasspointConfigurationWithOutPrivilegedPermissions() {
4668         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
4669         when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
4670                 false);
4671 
4672         mLooper.startAutoDispatch();
4673         mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME);
4674         mLooper.stopAutoDispatchAndIgnoreExceptions();
4675         verify(mPasspointManager).removeProvider(Binder.getCallingUid(), false, null,
4676                 TEST_FQDN);
4677     }
4678 
4679     /**
4680      * Verify the call to removePasspointConfigurations when the caller does have
4681      * NETWORK_CARRIER_PROVISIONING permission.
4682      */
4683     @Test
testRemovePasspointConfigurationWithPrivilegedPermissions()4684     public void testRemovePasspointConfigurationWithPrivilegedPermissions() {
4685         when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
4686                 true);
4687 
4688         mLooper.startAutoDispatch();
4689         mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME);
4690         mLooper.stopAutoDispatchAndIgnoreExceptions();
4691         verify(mPasspointManager).removeProvider(Binder.getCallingUid(), true, null,
4692                 TEST_FQDN);
4693     }
4694 
4695     /**
4696      * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from
4697      * callers with the signature only NETWORK_SETTINGS permission.
4698      */
4699     @Test(expected = SecurityException.class)
testRestoreBackupDataNotApprovedCaller()4700     public void testRestoreBackupDataNotApprovedCaller() {
4701         doThrow(new SecurityException()).when(mContext)
4702                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4703                         eq("WifiService"));
4704         mWifiServiceImpl.restoreBackupData(null);
4705         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class));
4706     }
4707 
testRestoreNetworkConfiguration(int configNum, int batchNum)4708     private void testRestoreNetworkConfiguration(int configNum, int batchNum) {
4709         List<WifiConfiguration> configurations = new ArrayList<>();
4710         when(mResources.getInteger(
4711                 eq(R.integer.config_wifiConfigurationRestoreNetworksBatchNum)))
4712                 .thenReturn(batchNum);
4713         WifiConfiguration config = new WifiConfiguration();
4714         config.SSID = TEST_SSID;
4715         for (int i = 0; i < configNum; i++) {
4716             configurations.add(config);
4717         }
4718         reset(mWifiConfigManager);
4719         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
4720                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
4721         mWifiServiceImpl.restoreNetworks(configurations);
4722         mLooper.dispatchAll();
4723         verify(mWifiConfigManager, times(configNum)).addOrUpdateNetwork(eq(config), anyInt());
4724         verify(mWifiConfigManager, times(configNum)).enableNetwork(
4725                 eq(TEST_NETWORK_ID), eq(false), anyInt(), eq(null));
4726         verify(mWifiConfigManager, times(configNum)).allowAutojoin(eq(TEST_NETWORK_ID),
4727                 anyBoolean());
4728     }
4729 
4730     /**
4731      * Verify that a call to
4732      * {@link WifiServiceImpl#restoreNetworks(List<WifiConfiguration> configurations)}
4733      * trigeering the process of the network restoration in batches.
4734      */
4735     @Test
testRestoreNetworksWithBatch()4736     public void testRestoreNetworksWithBatch() {
4737         testRestoreNetworkConfiguration(0 /* configNum */, 50 /* batchNum*/);
4738         testRestoreNetworkConfiguration(1 /* configNum */, 50 /* batchNum*/);
4739         testRestoreNetworkConfiguration(20 /* configNum */, 50 /* batchNum*/);
4740         testRestoreNetworkConfiguration(700 /* configNum */, 50 /* batchNum*/);
4741         testRestoreNetworkConfiguration(700 /* configNum */, 0 /* batchNum*/);
4742     }
4743 
4744     /**
4745      * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is
4746      * only allowed from callers with the signature only NETWORK_SETTINGS permission.
4747      */
4748     @Test(expected = SecurityException.class)
testRestoreSupplicantBackupDataNotApprovedCaller()4749     public void testRestoreSupplicantBackupDataNotApprovedCaller() {
4750         doThrow(new SecurityException()).when(mContext)
4751                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4752                         eq("WifiService"));
4753         mWifiServiceImpl.restoreSupplicantBackupData(null, null);
4754         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData(
4755                 any(byte[].class), any(byte[].class));
4756     }
4757 
4758     /**
4759      * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from
4760      * callers with the signature only NETWORK_SETTINGS permission.
4761      */
4762     @Test(expected = SecurityException.class)
testRetrieveBackupDataNotApprovedCaller()4763     public void testRetrieveBackupDataNotApprovedCaller() {
4764         doThrow(new SecurityException()).when(mContext)
4765                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4766                         eq("WifiService"));
4767         mWifiServiceImpl.retrieveBackupData();
4768         verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class));
4769     }
4770 
4771     /**
4772      * Verify that a call to {@link WifiServiceImpl#restoreSoftApBackupData(byte[])}
4773      * is only allowed from callers with the signature only NETWORK_SETTINGS permission.
4774      */
4775     @Test(expected = SecurityException.class)
testRestoreSoftApBackupDataNotApprovedCaller()4776     public void testRestoreSoftApBackupDataNotApprovedCaller() {
4777         doThrow(new SecurityException()).when(mContext)
4778                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4779                         eq("WifiService"));
4780         mWifiServiceImpl.restoreSoftApBackupData(null);
4781         verify(mSoftApBackupRestore, never())
4782                 .retrieveSoftApConfigurationFromBackupData(any(byte[].class));
4783     }
4784 
4785     /**
4786      * Verify that a call to {@link WifiServiceImpl#restoreSoftApBackupData(byte[])}
4787      * will call WifiApConfigStore#upgradeSoftApConfiguration and
4788      * WifiApConfigStore#resetToDefaultForUnsupportedConfig.
4789      */
4790     @Test
testRestoreSoftApBackupData()4791     public void testRestoreSoftApBackupData() {
4792         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4793             anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
4794         InOrder inorder = inOrder(mWifiApConfigStore);
4795         SoftApConfiguration testConfig = new SoftApConfiguration.Builder()
4796                 .setSsid("test").build();
4797         byte[] testData = testConfig.toString().getBytes();
4798         when(mSoftApBackupRestore.retrieveSoftApConfigurationFromBackupData(testData))
4799                 .thenReturn(testConfig);
4800         mWifiServiceImpl.restoreSoftApBackupData(testData);
4801         mLooper.dispatchAll();
4802         inorder.verify(mWifiApConfigStore).upgradeSoftApConfiguration(testConfig);
4803         inorder.verify(mWifiApConfigStore).resetToDefaultForUnsupportedConfig(any());
4804         inorder.verify(mWifiApConfigStore).setApConfiguration(any());
4805     }
4806 
4807     /**
4808      * Verify that a call to {@link WifiServiceImpl#retrieveSoftApBackupData()} is only allowed from
4809      * callers with the signature only NETWORK_SETTINGS permission.
4810      */
4811     @Test(expected = SecurityException.class)
testRetrieveSoftApBackupDataNotApprovedCaller()4812     public void testRetrieveSoftApBackupDataNotApprovedCaller() {
4813         doThrow(new SecurityException()).when(mContext)
4814                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4815                         eq("WifiService"));
4816         mWifiServiceImpl.retrieveSoftApBackupData();
4817         verify(mSoftApBackupRestore, never())
4818                 .retrieveBackupDataFromSoftApConfiguration(any(SoftApConfiguration.class));
4819     }
4820 
4821     class TestWifiVerboseLoggingStatusChangedListener extends
4822             IWifiVerboseLoggingStatusChangedListener.Stub {
4823         public int numStatusChangedCounts;
4824         public boolean lastReceivedValue;
4825         @Override
onStatusChanged(boolean enabled)4826         public void onStatusChanged(boolean enabled) throws RemoteException {
4827             numStatusChangedCounts++;
4828             lastReceivedValue = enabled;
4829         }
4830     }
4831 
4832     /**
4833      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is propagated to
4834      * registered {@link IWifiVerboseLoggingStatusChangedListener}. Then, verify that changes are no
4835      * longer propagated when the listener gets unregistered.
4836      */
4837     @Test
testVerboseLoggingListener()4838     public void testVerboseLoggingListener() throws Exception {
4839         doNothing().when(mContext)
4840                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4841                         eq("WifiService"));
4842         // Verbose logging is enabled first in the constructor for WifiServiceImpl, so reset
4843         // before invocation.
4844         reset(mClientModeManager);
4845         TestWifiVerboseLoggingStatusChangedListener listener =
4846                 new TestWifiVerboseLoggingStatusChangedListener();
4847         mWifiServiceImpl.addWifiVerboseLoggingStatusChangedListener(listener);
4848         mLooper.dispatchAll();
4849         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED);
4850         verify(mWifiSettingsConfigStore).put(WIFI_VERBOSE_LOGGING_ENABLED, true);
4851         verify(mActiveModeWarden).enableVerboseLogging(anyBoolean());
4852         assertEquals(1, listener.numStatusChangedCounts);
4853         assertTrue(listener.lastReceivedValue);
4854 
4855         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_DISABLED);
4856         assertEquals(2, listener.numStatusChangedCounts);
4857         assertFalse(listener.lastReceivedValue);
4858 
4859         // unregister the callback and verify no more updates happen.
4860         mWifiServiceImpl.removeWifiVerboseLoggingStatusChangedListener(listener);
4861         mLooper.dispatchAll();
4862         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED);
4863         assertEquals(2, listener.numStatusChangedCounts);
4864         assertFalse(listener.lastReceivedValue);
4865     }
4866 
4867     /**
4868      * Verify an exception is thrown for invalid inputs to
4869      * addWifiVerboseLoggingStatusChangedListener and removeWifiVerboseLoggingStatusChangedListener.
4870      */
4871     @Test
testVerboseLoggingListenerInvalidInput()4872     public void testVerboseLoggingListenerInvalidInput() throws Exception {
4873         try {
4874             mWifiServiceImpl.addWifiVerboseLoggingStatusChangedListener(null);
4875             fail("expected IllegalArgumentException in addWifiVerboseLoggingStatusChangedListener");
4876         } catch (IllegalArgumentException e) {
4877         }
4878         try {
4879             mWifiServiceImpl.removeWifiVerboseLoggingStatusChangedListener(null);
4880             fail("expected IllegalArgumentException in "
4881                     + "removeWifiVerboseLoggingStatusChangedListener");
4882         } catch (IllegalArgumentException e) {
4883         }
4884     }
4885 
4886     /**
4887      * Verify a SecurityException if the caller doesn't have sufficient permissions.
4888      */
4889     @Test
testVerboseLoggingListenerNoPermission()4890     public void testVerboseLoggingListenerNoPermission() throws Exception {
4891         doThrow(new SecurityException()).when(mContext)
4892                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
4893                         eq("WifiService"));
4894         TestWifiVerboseLoggingStatusChangedListener listener =
4895                 new TestWifiVerboseLoggingStatusChangedListener();
4896         try {
4897             mWifiServiceImpl.addWifiVerboseLoggingStatusChangedListener(listener);
4898             fail("expected IllegalArgumentException in addWifiVerboseLoggingStatusChangedListener");
4899         } catch (SecurityException e) {
4900         }
4901         try {
4902             mWifiServiceImpl.removeWifiVerboseLoggingStatusChangedListener(listener);
4903             fail("expected IllegalArgumentException in "
4904                     + "removeWifiVerboseLoggingStatusChangedListener");
4905         } catch (SecurityException e) {
4906         }
4907     }
4908 
4909     /**
4910      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is allowed from
4911      * callers with the signature only NETWORK_SETTINGS permission.
4912      */
4913     @Test
testEnableVerboseLoggingWithNetworkSettingsPermission()4914     public void testEnableVerboseLoggingWithNetworkSettingsPermission() throws Exception {
4915         doNothing().when(mContext)
4916                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4917                         eq("WifiService"));
4918         // Verbose logging is enabled first in the constructor for WifiServiceImpl, so reset
4919         // before invocation.
4920         reset(mClientModeManager);
4921         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED);
4922         verify(mWifiSettingsConfigStore).put(WIFI_VERBOSE_LOGGING_ENABLED, true);
4923         verify(mActiveModeWarden).enableVerboseLogging(anyBoolean());
4924     }
4925 
4926     /**
4927      * Verify that setting verbose logging mode to
4928      * {@link WifiManager#VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY)} is allowed from
4929      * callers with the signature only NETWORK_SETTINGS permission.
4930      */
4931     @Test
testEnableShowKeyVerboseLoggingWithNetworkSettingsPermission()4932     public void testEnableShowKeyVerboseLoggingWithNetworkSettingsPermission() throws Exception {
4933         doNothing().when(mContext)
4934                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4935                         eq("WifiService"));
4936         // Verbose logging is enabled first in the constructor for WifiServiceImpl, so reset
4937         // before invocation.
4938         reset(mClientModeManager);
4939         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY);
4940         verify(mWifiSettingsConfigStore).put(WIFI_VERBOSE_LOGGING_ENABLED, true);
4941         verify(mActiveModeWarden).enableVerboseLogging(anyBoolean());
4942         verify(mWifiGlobals).setShowKeyVerboseLoggingModeEnabled(eq(true));
4943 
4944         // After auto disable show key mode after the countdown
4945         mLooper.moveTimeForward(WifiServiceImpl.AUTO_DISABLE_SHOW_KEY_COUNTDOWN_MILLIS + 1);
4946         mLooper.dispatchAll();
4947         verify(mWifiGlobals).setShowKeyVerboseLoggingModeEnabled(eq(false));
4948     }
4949 
4950     /**
4951      * Verify that setting verbose logging level to
4952      * {@link WifiManager#VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY)} is not allowed for
4953      * the user build.
4954      */
4955     @Test(expected = SecurityException.class)
testEnableShowKeyVerboseLoggingNotAllowedForUserBuild()4956     public void testEnableShowKeyVerboseLoggingNotAllowedForUserBuild() throws Exception {
4957         when(mBuildProperties.isUserBuild()).thenReturn(true);
4958         doNothing().when(mContext)
4959                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4960                         eq("WifiService"));
4961         // Verbose logging is enabled first in the constructor for WifiServiceImpl, so reset
4962         // before invocation.
4963         reset(mClientModeManager);
4964         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY);
4965     }
4966 
4967     /**
4968      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is not allowed from
4969      * callers without the signature only NETWORK_SETTINGS permission.
4970      */
4971     @Test(expected = SecurityException.class)
testEnableVerboseLoggingWithNoNetworkSettingsPermission()4972     public void testEnableVerboseLoggingWithNoNetworkSettingsPermission() {
4973         doThrow(new SecurityException()).when(mContext)
4974                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
4975                         eq("WifiService"));
4976         // Vebose logging is enabled first in the constructor for WifiServiceImpl, so reset
4977         // before invocation.
4978         reset(mClientModeManager);
4979         mWifiServiceImpl.enableVerboseLogging(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED);
4980         verify(mWifiSettingsConfigStore, never()).put(
4981                 WIFI_VERBOSE_LOGGING_ENABLED, anyBoolean());
4982         verify(mActiveModeWarden, never()).enableVerboseLogging(anyBoolean());
4983     }
4984 
4985     /**
4986      * Verify that the CONNECT_NETWORK message received from an app without
4987      * one of the privileged permission is rejected with a security exception.
4988      */
4989     @Test
testConnectNetworkWithoutPrivilegedPermission()4990     public void testConnectNetworkWithoutPrivilegedPermission() throws Exception {
4991         try {
4992             mWifiServiceImpl.connect(mock(WifiConfiguration.class), TEST_NETWORK_ID,
4993                     mock(IActionListener.class), TEST_PACKAGE_NAME);
4994             fail();
4995         } catch (SecurityException e) {
4996             mLooper.dispatchAll();
4997             verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
4998         }
4999     }
5000 
5001     /**
5002      * Verify that the FORGET_NETWORK message received from an app without
5003      * one of the privileged permission is rejected with a security exception.
5004      */
5005     @Test
testForgetNetworkWithoutPrivilegedPermission()5006     public void testForgetNetworkWithoutPrivilegedPermission() throws Exception {
5007         try {
5008             mWifiServiceImpl.forget(TEST_NETWORK_ID, mock(IActionListener.class));
5009             fail();
5010         } catch (SecurityException e) {
5011             mLooper.dispatchAll();
5012             verify(mWifiConfigManager, never()).removeNetwork(anyInt(), anyInt(), any());
5013         }
5014     }
5015 
5016     /**
5017      * Verify that the SAVE_NETWORK message received from an app without
5018      * one of the privileged permission is rejected with a security exception.
5019      */
5020     @Test
testSaveNetworkWithoutPrivilegedPermission()5021     public void testSaveNetworkWithoutPrivilegedPermission() throws Exception {
5022         try {
5023             mWifiServiceImpl.save(mock(WifiConfiguration.class), mock(IActionListener.class),
5024                     TEST_PACKAGE_NAME);
5025             fail();
5026         } catch (SecurityException e) {
5027             mLooper.dispatchAll();
5028             verify(mWifiConfigManager, never()).updateBeforeSaveNetwork(any(), anyInt(), any());
5029         }
5030     }
5031 
5032     /**
5033      * Verify that the CONNECT_NETWORK message received from an app with
5034      * one of the privileged permission is forwarded to ClientModeManager.
5035      */
5036     @Test
testConnectNetworkWithPrivilegedPermission()5037     public void testConnectNetworkWithPrivilegedPermission() throws Exception {
5038         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5039             anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5040         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5041         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
5042                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
5043         WifiConfiguration config = new WifiConfiguration();
5044         config.SSID = TEST_SSID;
5045         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
5046         mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
5047                 TEST_PACKAGE_NAME);
5048         mLooper.dispatchAll();
5049         verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
5050         verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
5051                 any(ActionListenerWrapper.class), anyInt(), any());
5052         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
5053                 anyInt());
5054     }
5055 
5056     /**
5057      * Verify that the CONNECT_NETWORK message received from an app with
5058      * one of the privileged permission will stop secondary CMMs that are alraedy connected to
5059      * the same network before initiating the connection.
5060      */
5061     @Test
testConnectNetworkStopSecondaryCmmOnSameNetwork()5062     public void testConnectNetworkStopSecondaryCmmOnSameNetwork() throws Exception {
5063         // grant permissions to access WifiServiceImpl#connect
5064         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5065                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5066         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5067         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
5068                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
5069         WifiConfiguration config = WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork();
5070         config.SSID = TEST_SSID;
5071         WifiConfiguration localOnlyConfig = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
5072         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
5073 
5074         // Mock ActiveModeWarden to return a primary CMM and a secondary CMM to be already
5075         // connected to the target network.
5076         List<ClientModeManager> clientModeManagers = new ArrayList<>();
5077         ClientModeManager primaryCmm = mock(ClientModeManager.class);
5078         when(primaryCmm.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
5079         ClientModeManager localOnlyCmm = mock(ClientModeManager.class);
5080         when(localOnlyCmm.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY);
5081         when(localOnlyCmm.isConnected()).thenReturn(true);
5082         when(localOnlyCmm.getConnectedWifiConfiguration()).thenReturn(localOnlyConfig);
5083         clientModeManagers.add(primaryCmm);
5084         clientModeManagers.add(localOnlyCmm);
5085         when(mActiveModeWarden.getClientModeManagers()).thenReturn(clientModeManagers);
5086 
5087         // Verify that the localOnlyCmm is not stopped since security type is different
5088         mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
5089                 TEST_PACKAGE_NAME);
5090         mLooper.dispatchAll();
5091         verify(primaryCmm, never()).stop();
5092         verify(localOnlyCmm, never()).stop();
5093         verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
5094         verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
5095                 any(ActionListenerWrapper.class), anyInt(), any());
5096         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
5097                 anyInt());
5098 
5099         // update mock so that the localOnlyConfig matches with target config.
5100         localOnlyConfig = WifiConfigurationTestUtil.createWpa3EnterpriseNetwork(TEST_SSID);
5101         when(localOnlyCmm.getConnectedWifiConfiguration()).thenReturn(localOnlyConfig);
5102 
5103         // Verify that the localOnlyCmm is stopped this time
5104         mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
5105                 TEST_PACKAGE_NAME);
5106         mLooper.dispatchAll();
5107         verify(primaryCmm, never()).stop();
5108         verify(localOnlyCmm).stop();
5109         verify(mWifiConfigManager, times(2)).addOrUpdateNetwork(eq(config), anyInt());
5110         verify(mConnectHelper, times(2)).connectToNetwork(any(NetworkUpdateResult.class),
5111                 any(ActionListenerWrapper.class), anyInt(), any());
5112         verify(mWifiMetrics, times(2)).logUserActionEvent(
5113                 eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK), anyInt());
5114     }
5115 
5116     @Test
connectToNewNetwork_success()5117     public void connectToNewNetwork_success() throws Exception {
5118         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5119                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5120         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5121         NetworkUpdateResult result = new NetworkUpdateResult(TEST_NETWORK_ID);
5122         when(mWifiConfigManager.addOrUpdateNetwork(eq(mWifiConfig), anyInt()))
5123                 .thenReturn(result);
5124         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
5125 
5126         mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
5127                 mActionListener, TEST_PACKAGE_NAME);
5128         mLooper.dispatchAll();
5129 
5130         ArgumentCaptor<WifiConfiguration> configCaptor =
5131                 ArgumentCaptor.forClass(WifiConfiguration.class);
5132         verify(mWifiConfigManager).addOrUpdateNetwork(configCaptor.capture(), anyInt());
5133         assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
5134 
5135         verify(mConnectHelper).connectToNetwork(eq(result), any(), anyInt(), any());
5136         verify(mContextAsUser).sendBroadcastWithMultiplePermissions(
5137                 mIntentCaptor.capture(),
5138                 aryEq(new String[]{
5139                         android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE,
5140                         android.Manifest.permission.ACCESS_FINE_LOCATION,
5141                 }));
5142 
5143         Intent intent = mIntentCaptor.getValue();
5144         assertThat(intent.getAction()).isEqualTo(WifiManager.WIFI_CREDENTIAL_CHANGED_ACTION);
5145         assertThat(intent.getStringExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID))
5146                 .isEqualTo(TEST_SSID);
5147         assertThat(intent.getIntExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE, -1))
5148                 .isEqualTo(WifiManager.WIFI_CREDENTIAL_SAVED);
5149     }
5150 
5151     @Test
connectToNewNetwork_failure()5152     public void connectToNewNetwork_failure() throws Exception {
5153         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5154                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5155         when(mWifiConfigManager.addOrUpdateNetwork(eq(mWifiConfig), anyInt()))
5156                 .thenReturn(NetworkUpdateResult.makeFailed());
5157         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5158 
5159         mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
5160                 mActionListener, TEST_PACKAGE_NAME);
5161         mLooper.dispatchAll();
5162 
5163         verify(mWifiConfigManager).addOrUpdateNetwork(eq(mWifiConfig), anyInt());
5164 
5165         verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
5166         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5167         verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5168         verify(mActionListener, never()).onSuccess();
5169     }
5170 
5171     @Test
connectToExistingNetwork()5172     public void connectToExistingNetwork() throws Exception {
5173         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5174                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5175         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5176         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5177         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
5178 
5179         mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
5180         mLooper.dispatchAll();
5181 
5182         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
5183 
5184         verify(mConnectHelper).connectToNetwork(
5185                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
5186         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5187         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
5188     }
5189 
5190     @Test
connectToSimBasedNetworkWhenSimPresent()5191     public void connectToSimBasedNetworkWhenSimPresent() {
5192         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
5193                 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
5194         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5195                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5196         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5197         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5198         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
5199         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
5200         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(true);
5201 
5202         mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
5203         mLooper.dispatchAll();
5204 
5205         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
5206 
5207         verify(mConnectHelper).connectToNetwork(
5208                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
5209         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5210         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
5211     }
5212 
5213     @Test
connectToSimBasedNetworkWhenSimAbsent()5214     public void connectToSimBasedNetworkWhenSimAbsent() {
5215         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
5216                 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
5217         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5218                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5219         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5220         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5221         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
5222         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
5223         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(false);
5224 
5225         mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
5226         mLooper.dispatchAll();
5227 
5228         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
5229 
5230         verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
5231         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5232         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
5233     }
5234 
5235     @Test
connectToSimBasedNetworkRequiresImsiEncryptionButNotReady()5236     public void connectToSimBasedNetworkRequiresImsiEncryptionButNotReady() {
5237         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
5238                 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
5239         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5240                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5241         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5242         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5243         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
5244         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
5245         when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(false);
5246         when(mWifiCarrierInfoManager.requiresImsiEncryption(TEST_SUB_ID)).thenReturn(true);
5247         when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(TEST_SUB_ID)).thenReturn(false);
5248 
5249         mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
5250         mLooper.dispatchAll();
5251 
5252         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
5253 
5254         verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
5255         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5256         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
5257     }
5258 
5259     /**
5260      * Verify that connecting to an admin restricted network fails to connect but saves the network
5261      */
5262     @Test
connectToAdminRestrictedNetwork_failure()5263     public void connectToAdminRestrictedNetwork_failure() throws Exception {
5264         assumeTrue(SdkLevel.isAtLeastT());
5265         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5266                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5267         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5268         NetworkUpdateResult result = new NetworkUpdateResult(TEST_NETWORK_ID);
5269         when(mWifiConfigManager.addOrUpdateNetwork(eq(mWifiConfig), anyInt()))
5270                 .thenReturn(result);
5271         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
5272         when(mWifiPermissionsUtil.isAdminRestrictedNetwork(mWifiConfig)).thenReturn(true);
5273 
5274         mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
5275                 mActionListener, TEST_PACKAGE_NAME);
5276         mLooper.dispatchAll();
5277 
5278         ArgumentCaptor<WifiConfiguration> configCaptor =
5279                 ArgumentCaptor.forClass(WifiConfiguration.class);
5280         verify(mWifiConfigManager).addOrUpdateNetwork(configCaptor.capture(), anyInt());
5281         assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
5282 
5283         verify(mWifiConfigManager).addOrUpdateNetwork(eq(mWifiConfig), anyInt());
5284         verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
5285         verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5286         verify(mActionListener, never()).onSuccess();
5287     }
5288 
5289     /**
5290      * Verify that the SAVE_NETWORK message received from an app with
5291      * one of the privileged permission is forwarded to ClientModeManager.
5292      */
5293     @Test
testSaveNetworkWithPrivilegedPermission()5294     public void testSaveNetworkWithPrivilegedPermission() throws Exception {
5295         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5296             anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5297         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5298         when(mWifiConfigManager.updateBeforeSaveNetwork(any(), anyInt(), any()))
5299                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
5300         mWifiServiceImpl.save(mock(WifiConfiguration.class), mock(IActionListener.class),
5301                 TEST_PACKAGE_NAME);
5302         mLooper.dispatchAll();
5303         verify(mWifiConfigManager).updateBeforeSaveNetwork(any(WifiConfiguration.class), anyInt(),
5304                 any());
5305         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
5306                 anyInt());
5307     }
5308 
5309     @Test
saveNetwork_success()5310     public void saveNetwork_success() throws Exception {
5311         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5312                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5313         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5314 
5315         NetworkUpdateResult result = new NetworkUpdateResult(TEST_NETWORK_ID);
5316         when(mWifiConfigManager.updateBeforeSaveNetwork(eq(mWifiConfig), anyInt(), any()))
5317                 .thenReturn(result);
5318 
5319         mWifiServiceImpl.save(mWifiConfig, mActionListener, TEST_PACKAGE_NAME);
5320         mLooper.dispatchAll();
5321 
5322         verify(mWifiConfigManager).updateBeforeSaveNetwork(eq(mWifiConfig), anyInt(), any());
5323 
5324         verify(mClientModeManager).saveNetwork(eq(result), any(), anyInt(), any());
5325         verify(mContextAsUser).sendBroadcastWithMultiplePermissions(
5326                 mIntentCaptor.capture(),
5327                 aryEq(new String[]{
5328                         android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE,
5329                         android.Manifest.permission.ACCESS_FINE_LOCATION,
5330                 }));
5331 
5332         Intent intent = mIntentCaptor.getValue();
5333         assertThat(intent.getAction()).isEqualTo(WifiManager.WIFI_CREDENTIAL_CHANGED_ACTION);
5334         assertThat(intent.getStringExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID))
5335                 .isEqualTo(TEST_SSID);
5336         assertThat(intent.getIntExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE, -1))
5337                 .isEqualTo(WifiManager.WIFI_CREDENTIAL_SAVED);
5338     }
5339 
5340     @Test
saveNetwork_failure()5341     public void saveNetwork_failure() throws Exception {
5342         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5343                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5344         when(mWifiConfigManager.updateBeforeSaveNetwork(eq(mWifiConfig), anyInt(), any()))
5345                 .thenReturn(NetworkUpdateResult.makeFailed());
5346         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5347 
5348         mWifiServiceImpl.save(mWifiConfig, mActionListener, TEST_PACKAGE_NAME);
5349         mLooper.dispatchAll();
5350 
5351         verify(mWifiConfigManager).updateBeforeSaveNetwork(eq(mWifiConfig), anyInt(), any());
5352 
5353         verify(mClientModeManager, never()).saveNetwork(any(), any(), anyInt(), any());
5354         verify(mContext, never()).sendBroadcastWithMultiplePermissions(any(), any());
5355         verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5356         verify(mActionListener, never()).onSuccess();
5357     }
5358 
5359     /**
5360      * Verify that the FORGET_NETWORK message received from an app with
5361      * one of the privileged permission is forwarded to ClientModeManager.
5362      */
5363     @Test
testForgetNetworkWithPrivilegedPermission()5364     public void testForgetNetworkWithPrivilegedPermission() throws Exception {
5365         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5366             anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5367         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
5368         when(mWifiConfigManager.removeNetwork(anyInt(), anyInt(), any())).thenReturn(true);
5369         mWifiServiceImpl.forget(TEST_NETWORK_ID, mock(IActionListener.class));
5370 
5371         InOrder inOrder = inOrder(mWifiConfigManager, mWifiMetrics);
5372         inOrder.verify(mWifiMetrics).logUserActionEvent(
5373                 UserActionEvent.EVENT_FORGET_WIFI, TEST_NETWORK_ID);
5374 
5375         mLooper.dispatchAll();
5376         inOrder.verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), any());
5377     }
5378 
5379     @Test
forgetNetwork_success()5380     public void forgetNetwork_success() throws Exception {
5381         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5382                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5383         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
5384         when(mWifiConfigManager.removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any()))
5385                 .thenReturn(true);
5386         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5387 
5388         mWifiServiceImpl.forget(TEST_NETWORK_ID, mActionListener);
5389         mLooper.dispatchAll();
5390 
5391         verify(mWifiConfigManager).removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any());
5392         verify(mActionListener).onSuccess();
5393         verify(mActionListener, never())
5394                 .onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5395 
5396         verify(mContextAsUser).sendBroadcastWithMultiplePermissions(
5397                 mIntentCaptor.capture(),
5398                 aryEq(new String[]{
5399                         android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE,
5400                         android.Manifest.permission.ACCESS_FINE_LOCATION,
5401                 }));
5402 
5403         Intent intent = mIntentCaptor.getValue();
5404         assertThat(intent.getAction()).isEqualTo(WifiManager.WIFI_CREDENTIAL_CHANGED_ACTION);
5405         assertThat(intent.getStringExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID))
5406                 .isEqualTo(TEST_SSID);
5407         assertThat(intent.getIntExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE, -1))
5408                 .isEqualTo(WifiManager.WIFI_CREDENTIAL_FORGOT);
5409     }
5410 
5411     @Test
forgetNetwork_successNoLocation_dontBroadcastSsid()5412     public void forgetNetwork_successNoLocation_dontBroadcastSsid() throws Exception {
5413         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
5414 
5415         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5416                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5417         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
5418         when(mWifiConfigManager.removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any()))
5419                 .thenReturn(true);
5420 
5421         mWifiServiceImpl.forget(TEST_NETWORK_ID, mActionListener);
5422         mLooper.dispatchAll();
5423 
5424         verify(mWifiConfigManager).removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any());
5425         verify(mActionListener).onSuccess();
5426         verify(mActionListener, never())
5427                 .onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5428 
5429         verify(mContextAsUser).sendBroadcastWithMultiplePermissions(
5430                 mIntentCaptor.capture(),
5431                 aryEq(new String[]{
5432                         android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE,
5433                         android.Manifest.permission.ACCESS_FINE_LOCATION,
5434                 }));
5435 
5436         Intent intent = mIntentCaptor.getValue();
5437         assertThat(intent.getAction()).isEqualTo(WifiManager.WIFI_CREDENTIAL_CHANGED_ACTION);
5438         // SSID is null if location is disabled
5439         assertThat(intent.getStringExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID)).isNull();
5440         assertThat(intent.getIntExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE, -1))
5441                 .isEqualTo(WifiManager.WIFI_CREDENTIAL_FORGOT);
5442     }
5443 
5444     @Test
forgetNetwork_failed()5445     public void forgetNetwork_failed() throws Exception {
5446         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5447                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5448         when(mWifiConfigManager.removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any()))
5449                 .thenReturn(false);
5450         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
5451 
5452         mWifiServiceImpl.forget(TEST_NETWORK_ID, mActionListener);
5453         mLooper.dispatchAll();
5454 
5455         verify(mActionListener, never()).onSuccess();
5456         verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
5457         verify(mWifiConfigManager).removeNetwork(eq(TEST_NETWORK_ID), anyInt(), any());
5458         verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
5459     }
5460 
5461     /**
5462      * Tests the scenario when a scan request arrives while the device is idle. In this case
5463      * the scan is done when idle mode ends.
5464      */
5465     @Test
testHandleDelayedScanAfterIdleMode()5466     public void testHandleDelayedScanAfterIdleMode() throws Exception {
5467         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
5468         when(mWifiInjector.getPasspointProvisionerHandlerThread())
5469                 .thenReturn(mock(HandlerThread.class));
5470         mLooper.startAutoDispatch();
5471         mWifiServiceImpl.checkAndStartWifi();
5472         mWifiServiceImpl.handleBootCompleted();
5473         mLooper.stopAutoDispatch();
5474         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5475                 (IntentFilter) argThat(new IdleModeIntentMatcher()),
5476                 isNull(),
5477                 any(Handler.class));
5478 
5479         // Tell the wifi service that the device became idle.
5480         when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
5481         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
5482 
5483         // Send a scan request while the device is idle.
5484         mWifiThreadRunner.prepareForAutoDispatch();
5485         mLooper.startAutoDispatch();
5486         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
5487         mLooper.stopAutoDispatch();
5488         // No scans must be made yet as the device is idle.
5489         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
5490 
5491         // Tell the wifi service that idle mode ended.
5492         when(mPowerManager.isDeviceIdleMode()).thenReturn(false);
5493         mWifiThreadRunner.prepareForAutoDispatch();
5494         mLooper.startAutoDispatch();
5495         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
5496         mLooper.stopAutoDispatch();
5497 
5498         // Must scan now.
5499         verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME);
5500         // The app ops check is executed with this package's identity (not the identity of the
5501         // original remote caller who requested the scan while idle).
5502         verify(mAppOpsManager).noteOp(
5503                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
5504 
5505         // Send another scan request. The device is not idle anymore, so it must be executed
5506         // immediately.
5507         mWifiThreadRunner.prepareForAutoDispatch();
5508         mLooper.startAutoDispatch();
5509         assertTrue(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
5510         mLooper.stopAutoDispatch();
5511         verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
5512     }
5513 
5514     /**
5515      * Verify that if the caller has NETWORK_SETTINGS permission, then it doesn't need
5516      * CHANGE_WIFI_STATE permission.
5517      */
5518     @Test
testDisconnectWithNetworkSettingsPerm()5519     public void testDisconnectWithNetworkSettingsPerm() throws Exception {
5520         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5521                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
5522         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
5523                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
5524         doThrow(new SecurityException()).when(mAppOpsManager)
5525                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
5526         assertTrue(mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME));
5527         mLooper.dispatchAll();
5528         verify(mClientModeManager).disconnect();
5529     }
5530 
5531     /**
5532      * Verify that if the caller doesn't have NETWORK_SETTINGS permission, it could still
5533      * get access with the CHANGE_WIFI_STATE permission.
5534      */
5535     @Test
testDisconnectWithChangeWifiStatePerm()5536     public void testDisconnectWithChangeWifiStatePerm() throws Exception {
5537         assertFalse(mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME));
5538         mLooper.dispatchAll();
5539         verifyCheckChangePermission(TEST_PACKAGE_NAME);
5540         verify(mClientModeManager, never()).disconnect();
5541     }
5542 
5543     /**
5544      * Verify that the operation fails if the caller has neither NETWORK_SETTINGS or
5545      * CHANGE_WIFI_STATE permissions.
5546      */
5547     @Test
testDisconnectRejected()5548     public void testDisconnectRejected() throws Exception {
5549         doThrow(new SecurityException()).when(mAppOpsManager)
5550                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
5551         try {
5552             mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME);
5553             fail();
5554         } catch (SecurityException e) {
5555 
5556         }
5557         verifyCheckChangePermission(TEST_PACKAGE_NAME);
5558         verify(mClientModeManager, never()).disconnect();
5559     }
5560 
5561     @Test
testPackageFullyRemovedBroadcastHandling()5562     public void testPackageFullyRemovedBroadcastHandling() throws Exception {
5563         mWifiServiceImpl.checkAndStartWifi();
5564         mLooper.dispatchAll();
5565         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5566                 argThat((IntentFilter filter) ->
5567                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
5568                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
5569                                 && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
5570                 isNull(),
5571                 any(Handler.class));
5572         int uid = TEST_UID;
5573         String packageName = TEST_PACKAGE_NAME;
5574         doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager)
5575                 .getApplicationInfo(TEST_PACKAGE_NAME, 0);
5576         // Send the broadcast
5577         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
5578         intent.putExtra(Intent.EXTRA_UID, uid);
5579         intent.setData(Uri.fromParts("package", packageName, ""));
5580         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5581         mLooper.dispatchAll();
5582 
5583         ArgumentCaptor<ApplicationInfo> aiCaptor = ArgumentCaptor.forClass(ApplicationInfo.class);
5584         verify(mWifiConfigManager).removeNetworksForApp(aiCaptor.capture());
5585         assertNotNull(aiCaptor.getValue());
5586         assertEquals(uid, aiCaptor.getValue().uid);
5587         assertEquals(packageName, aiCaptor.getValue().packageName);
5588 
5589         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
5590         verify(mWifiNetworkSuggestionsManager).removeApp(packageName);
5591         verify(mWifiNetworkFactory).removeUserApprovedAccessPointsForApp(packageName);
5592         verify(mPasspointManager).removePasspointProviderWithPackage(packageName);
5593     }
5594 
5595     @Test
testPackageRemovedBroadcastHandling()5596     public void testPackageRemovedBroadcastHandling() throws Exception {
5597         mWifiServiceImpl.checkAndStartWifi();
5598         mLooper.dispatchAll();
5599         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5600                 argThat((IntentFilter filter) ->
5601                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
5602                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
5603                                 && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
5604                 isNull(),
5605                 any(Handler.class));
5606         int uid = TEST_UID;
5607         String packageName = TEST_PACKAGE_NAME;
5608         // Send the broadcast
5609         Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
5610         intent.putExtra(Intent.EXTRA_UID, uid);
5611         intent.setData(Uri.fromParts("package", packageName, ""));
5612         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5613         mLooper.dispatchAll();
5614 
5615         ArgumentCaptor<ApplicationInfo> aiCaptor = ArgumentCaptor.forClass(ApplicationInfo.class);
5616         verify(mWifiConfigManager).removeNetworksForApp(aiCaptor.capture());
5617         assertNotNull(aiCaptor.getValue());
5618         assertEquals(uid, aiCaptor.getValue().uid);
5619         assertEquals(packageName, aiCaptor.getValue().packageName);
5620 
5621         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
5622         verify(mWifiNetworkSuggestionsManager).removeApp(packageName);
5623         verify(mWifiNetworkFactory).removeUserApprovedAccessPointsForApp(packageName);
5624         verify(mPasspointManager).removePasspointProviderWithPackage(packageName);
5625     }
5626 
5627     @Test
testPackageDisableBroadcastHandling()5628     public void testPackageDisableBroadcastHandling() throws Exception {
5629         mWifiServiceImpl.checkAndStartWifi();
5630         mLooper.dispatchAll();
5631         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5632                 argThat((IntentFilter filter) ->
5633                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
5634                                 && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
5635                                 && filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)),
5636                 isNull(),
5637                 any(Handler.class));
5638         int uid = TEST_UID;
5639         String packageName = TEST_PACKAGE_NAME;
5640         mPackageInfo.applicationInfo = mApplicationInfo;
5641         mApplicationInfo.enabled = false;
5642         // Send the broadcast
5643         Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
5644         intent.putExtra(Intent.EXTRA_UID, uid);
5645         intent.setData(Uri.fromParts("package", packageName, ""));
5646         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5647         mLooper.dispatchAll();
5648 
5649         ArgumentCaptor<ApplicationInfo> aiCaptor = ArgumentCaptor.forClass(ApplicationInfo.class);
5650         verify(mWifiConfigManager).removeNetworksForApp(aiCaptor.capture());
5651         assertNotNull(aiCaptor.getValue());
5652         assertEquals(uid, aiCaptor.getValue().uid);
5653         assertEquals(packageName, aiCaptor.getValue().packageName);
5654 
5655         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
5656         verify(mWifiNetworkSuggestionsManager).removeApp(packageName);
5657         verify(mWifiNetworkFactory).removeUserApprovedAccessPointsForApp(packageName);
5658         verify(mPasspointManager).removePasspointProviderWithPackage(packageName);
5659     }
5660 
5661     @Test
testPackageRemovedBroadcastHandlingWithNoUid()5662     public void testPackageRemovedBroadcastHandlingWithNoUid() {
5663         mWifiServiceImpl.checkAndStartWifi();
5664         mLooper.dispatchAll();
5665         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5666                 argThat((IntentFilter filter) ->
5667                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)),
5668                 isNull(),
5669                 any(Handler.class));
5670 
5671         String packageName = TEST_PACKAGE_NAME;
5672         // Send the broadcast
5673         Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
5674         intent.setData(Uri.fromParts("package", packageName, ""));
5675         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5676 
5677         verify(mWifiConfigManager, never()).removeNetworksForApp(any());
5678 
5679         mLooper.dispatchAll();
5680         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
5681         verify(mWifiNetworkSuggestionsManager, never()).removeApp(anyString());
5682         verify(mWifiNetworkFactory, never()).removeUserApprovedAccessPointsForApp(anyString());
5683         verify(mPasspointManager, never()).removePasspointProviderWithPackage(anyString());
5684     }
5685 
5686     @Test
testPackageRemovedBroadcastHandlingWithNoPackageName()5687     public void testPackageRemovedBroadcastHandlingWithNoPackageName() {
5688         mWifiServiceImpl.checkAndStartWifi();
5689         mLooper.dispatchAll();
5690         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5691                 argThat((IntentFilter filter) ->
5692                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)),
5693                 isNull(),
5694                 any(Handler.class));
5695 
5696         int uid = TEST_UID;
5697         // Send the broadcast
5698         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
5699         intent.putExtra(Intent.EXTRA_UID, uid);
5700         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5701 
5702         verify(mWifiConfigManager, never()).removeNetworksForApp(any());
5703 
5704         mLooper.dispatchAll();
5705         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
5706         verify(mWifiNetworkSuggestionsManager, never()).removeApp(anyString());
5707         verify(mWifiNetworkFactory, never()).removeUserApprovedAccessPointsForApp(anyString());
5708         verify(mPasspointManager, never()).removePasspointProviderWithPackage(anyString());
5709     }
5710 
5711     @Test
testUserRemovedBroadcastHandling()5712     public void testUserRemovedBroadcastHandling() {
5713         when(mWifiInjector.getPasspointProvisionerHandlerThread())
5714                 .thenReturn(mock(HandlerThread.class));
5715         mLooper.startAutoDispatch();
5716         mWifiServiceImpl.checkAndStartWifi();
5717         mWifiServiceImpl.handleBootCompleted();
5718         mLooper.stopAutoDispatch();
5719         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5720                 argThat((IntentFilter filter) ->
5721                         filter.hasAction(Intent.ACTION_USER_REMOVED)),
5722                 isNull(),
5723                 any(Handler.class));
5724 
5725         UserHandle userHandle = UserHandle.of(TEST_USER_HANDLE);
5726         // Send the broadcast
5727         Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
5728         intent.putExtra(Intent.EXTRA_USER, userHandle);
5729         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5730         mLooper.dispatchAll();
5731 
5732         verify(mWifiConfigManager).removeNetworksForUser(userHandle.getIdentifier());
5733     }
5734 
5735     @Test
testBluetoothBroadcastHandling()5736     public void testBluetoothBroadcastHandling() {
5737         when(mWifiInjector.getPasspointProvisionerHandlerThread())
5738                 .thenReturn(mock(HandlerThread.class));
5739         mLooper.startAutoDispatch();
5740         mWifiServiceImpl.checkAndStartWifi();
5741         mWifiServiceImpl.handleBootCompleted();
5742         mLooper.stopAutoDispatch();
5743         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5744                 argThat((IntentFilter filter) ->
5745                         filter.hasAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
5746                                 && filter.hasAction(BluetoothAdapter.ACTION_STATE_CHANGED)),
5747                 isNull(),
5748                 any(Handler.class));
5749 
5750         {
5751             Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
5752             intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
5753                     BluetoothAdapter.STATE_DISCONNECTED);
5754             mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5755             mLooper.dispatchAll();
5756 
5757             verify(mWifiGlobals).setBluetoothConnected(false);
5758             for (ClientModeManager cmm : mClientModeManagers) {
5759                 verify(cmm).onBluetoothConnectionStateChanged();
5760             }
5761         }
5762 
5763         {
5764             Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
5765             intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
5766                     BluetoothAdapter.STATE_CONNECTED);
5767             mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5768             mLooper.dispatchAll();
5769 
5770             verify(mWifiGlobals).setBluetoothConnected(true);
5771             for (ClientModeManager cmm : mClientModeManagers) {
5772                 verify(cmm, times(2)).onBluetoothConnectionStateChanged();
5773             }
5774         }
5775 
5776         {
5777             Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
5778             intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
5779             mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5780             mLooper.dispatchAll();
5781 
5782             verify(mWifiGlobals).setBluetoothEnabled(false);
5783             for (ClientModeManager cmm : mClientModeManagers) {
5784                 verify(cmm, times(3)).onBluetoothConnectionStateChanged();
5785             }
5786         }
5787 
5788         {
5789             Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
5790             intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
5791             mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5792             mLooper.dispatchAll();
5793 
5794             verify(mWifiGlobals).setBluetoothEnabled(true);
5795             for (ClientModeManager cmm : mClientModeManagers) {
5796                 verify(cmm, times(4)).onBluetoothConnectionStateChanged();
5797             }
5798         }
5799     }
5800 
5801     @Test
testUserRemovedBroadcastHandlingWithWrongIntentAction()5802     public void testUserRemovedBroadcastHandlingWithWrongIntentAction() {
5803         when(mWifiInjector.getPasspointProvisionerHandlerThread())
5804                 .thenReturn(mock(HandlerThread.class));
5805         mLooper.startAutoDispatch();
5806         mWifiServiceImpl.checkAndStartWifi();
5807         mWifiServiceImpl.handleBootCompleted();
5808         mLooper.stopAutoDispatch();
5809         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5810                 argThat((IntentFilter filter) ->
5811                         filter.hasAction(Intent.ACTION_USER_REMOVED)),
5812                 isNull(),
5813                 any(Handler.class));
5814 
5815         UserHandle userHandle = UserHandle.of(TEST_USER_HANDLE);
5816         // Send the broadcast with wrong action
5817         Intent intent = new Intent(Intent.ACTION_USER_FOREGROUND);
5818         intent.putExtra(Intent.EXTRA_USER, userHandle);
5819         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5820 
5821         verify(mWifiConfigManager, never()).removeNetworksForUser(anyInt());
5822     }
5823 
5824     private class IdleModeIntentMatcher implements ArgumentMatcher<IntentFilter> {
5825         @Override
matches(IntentFilter filter)5826         public boolean matches(IntentFilter filter) {
5827             return filter.hasAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
5828         }
5829     }
5830 
5831     /**
5832      * Verifies that enforceChangePermission(String package) is called and the caller doesn't
5833      * have NETWORK_SETTINGS permission
5834      */
verifyCheckChangePermission(String callingPackageName)5835     private void verifyCheckChangePermission(String callingPackageName) {
5836         verify(mContext, atLeastOnce())
5837                 .checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5838                         anyInt(), anyInt());
5839         verify(mContext, atLeastOnce()).enforceCallingOrSelfPermission(
5840                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
5841         verify(mAppOpsManager, atLeastOnce()).noteOp(
5842                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), callingPackageName);
5843     }
5844 
createValidWifiApConfiguration()5845     private WifiConfiguration createValidWifiApConfiguration() {
5846         WifiConfiguration apConfig = new WifiConfiguration();
5847         apConfig.SSID = "TestAp";
5848         apConfig.preSharedKey = "thisIsABadPassword";
5849         apConfig.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
5850         apConfig.apBand = WifiConfiguration.AP_BAND_2GHZ;
5851 
5852         return apConfig;
5853     }
5854 
createValidSoftApConfiguration()5855     private SoftApConfiguration createValidSoftApConfiguration() {
5856         return new SoftApConfiguration.Builder()
5857                 .setSsid("TestAp")
5858                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
5859                 .setBand(SoftApConfiguration.BAND_2GHZ)
5860                 .build();
5861     }
5862 
5863     /**
5864      * Verifies that sim state change does not set or reset the country code
5865      */
5866     @Test
testSimStateChangeDoesNotResetCountryCode()5867     public void testSimStateChangeDoesNotResetCountryCode() {
5868         mWifiServiceImpl.checkAndStartWifi();
5869         mLooper.dispatchAll();
5870         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5871                 (IntentFilter) argThat((IntentFilter filter) ->
5872                         filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
5873                 isNull(),
5874                 any(Handler.class));
5875 
5876         int userHandle = TEST_USER_HANDLE;
5877         // Send the broadcast
5878         Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
5879         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
5880         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5881         verify(mWifiCountryCode, never()).setTelephonyCountryCodeAndUpdate(any());
5882     }
5883 
5884     /**
5885      * Verifies that sim state change does not set or reset the country code
5886      */
5887     @Test
testSimStateChangeDoesNotResetCountryCodeForRebroadcastedIntent()5888     public void testSimStateChangeDoesNotResetCountryCodeForRebroadcastedIntent() {
5889         mWifiServiceImpl.checkAndStartWifi();
5890         mLooper.dispatchAll();
5891         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5892                 (IntentFilter) argThat((IntentFilter filter) ->
5893                         filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
5894                 isNull(),
5895                 any(Handler.class));
5896 
5897         int userHandle = TEST_USER_HANDLE;
5898         // Send the broadcast
5899         Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
5900         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
5901         intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, Intent.SIM_STATE_ABSENT);
5902         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5903         verify(mWifiCountryCode, never()).setTelephonyCountryCodeAndUpdate(any());
5904     }
5905 
5906     /**
5907      * Verify removing sim will also remove an ephemeral Passpoint Provider. And reset carrier
5908      * privileged suggestor apps.
5909      */
5910     @Test
testResetSimNetworkWhenRemovingSim()5911     public void testResetSimNetworkWhenRemovingSim() throws Exception {
5912         mWifiServiceImpl.checkAndStartWifi();
5913         mLooper.dispatchAll();
5914         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5915                 argThat((IntentFilter filter) ->
5916                         filter.hasAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)),
5917                 isNull(),
5918                 any(Handler.class));
5919 
5920         Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
5921         intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_ABSENT);
5922         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5923         mLooper.dispatchAll();
5924 
5925         verify(mWifiConfigManager).resetSimNetworks();
5926         verify(mWifiConfigManager).stopRestrictingAutoJoinToSubscriptionId();
5927         verify(mSimRequiredNotifier, never()).dismissSimRequiredNotification();
5928         verify(mWifiNetworkSuggestionsManager).updateCarrierPrivilegedApps();
5929         verify(mWifiConfigManager, never()).removeAllEphemeralOrPasspointConfiguredNetworks();
5930         verify(mWifiNetworkSuggestionsManager).resetSimNetworkSuggestions();
5931         verify(mPasspointManager).resetSimPasspointNetwork();
5932     }
5933 
5934     /**
5935      * Verify inserting sim will reset carrier privileged suggestor apps.
5936      * and remove any previous notifications due to sim removal
5937      */
5938     @Test
testResetCarrierPrivilegedAppsWhenInsertingSim()5939     public void testResetCarrierPrivilegedAppsWhenInsertingSim() throws Exception {
5940         mWifiServiceImpl.checkAndStartWifi();
5941         mLooper.dispatchAll();
5942         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5943                 argThat((IntentFilter filter) ->
5944                         filter.hasAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)),
5945                 isNull(),
5946                 any(Handler.class));
5947 
5948         Intent intent = new Intent(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
5949         intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_LOADED);
5950         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5951         mLooper.dispatchAll();
5952 
5953         verify(mWifiConfigManager, never()).resetSimNetworks();
5954         verify(mPasspointManager, never()).resetSimPasspointNetwork();
5955         verify(mWifiNetworkSuggestionsManager, never()).resetSimNetworkSuggestions();
5956         verify(mWifiConfigManager, never()).stopRestrictingAutoJoinToSubscriptionId();
5957         verify(mSimRequiredNotifier).dismissSimRequiredNotification();
5958         verify(mWifiNetworkSuggestionsManager).updateCarrierPrivilegedApps();
5959         verify(mWifiConfigManager, never()).removeAllEphemeralOrPasspointConfiguredNetworks();
5960         verify(mWifiConfigManager).enableTemporaryDisabledNetworks();
5961         verify(mWifiConnectivityManager).forceConnectivityScan(any());
5962     }
5963 
5964     @Test
testResetSimNetworkWhenDefaultDataSimChanged()5965     public void testResetSimNetworkWhenDefaultDataSimChanged() throws Exception {
5966         mWifiServiceImpl.checkAndStartWifi();
5967         mLooper.dispatchAll();
5968         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
5969                 argThat((IntentFilter filter) ->
5970                         filter.hasAction(
5971                                 TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)),
5972                 isNull(),
5973                 any(Handler.class));
5974 
5975         Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
5976         intent.putExtra("subscription", 1);
5977         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
5978         mLooper.dispatchAll();
5979 
5980         verify(mWifiConfigManager).resetSimNetworks();
5981         verify(mWifiConfigManager).stopRestrictingAutoJoinToSubscriptionId();
5982         verify(mSimRequiredNotifier, never()).dismissSimRequiredNotification();
5983         verify(mWifiNetworkSuggestionsManager).updateCarrierPrivilegedApps();
5984         verify(mWifiConfigManager).removeEphemeralCarrierNetworks(anySet());
5985         verify(mWifiNetworkSuggestionsManager).resetSimNetworkSuggestions();
5986         verify(mPasspointManager).resetSimPasspointNetwork();
5987         verify(mWifiDataStall).resetPhoneStateListener();
5988     }
5989 
5990     /**
5991      * Verify that a call to registerTrafficStateCallback throws a SecurityException if the caller
5992      * does not have NETWORK_SETTINGS permission.
5993      */
5994     @Test
registerTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions()5995     public void registerTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions() {
5996         doThrow(new SecurityException()).when(mContext)
5997                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
5998                         eq("WifiService"));
5999         try {
6000             mWifiServiceImpl.registerTrafficStateCallback(mTrafficStateCallback);
6001             fail("expected SecurityException");
6002         } catch (SecurityException expected) {
6003         }
6004     }
6005 
6006     /**
6007      * Verify that a call to registerTrafficStateCallback throws an IllegalArgumentException if the
6008      * parameters are not provided.
6009      */
6010     @Test
registerTrafficStateCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()6011     public void registerTrafficStateCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
6012         try {
6013             mWifiServiceImpl.registerTrafficStateCallback(null);
6014             fail("expected IllegalArgumentException");
6015         } catch (IllegalArgumentException expected) {
6016         }
6017     }
6018 
6019     /**
6020      * Verify that a call to unregisterTrafficStateCallback throws a SecurityException if the caller
6021      * does not have NETWORK_SETTINGS permission.
6022      */
6023     @Test
unregisterTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions()6024     public void unregisterTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions() {
6025         doThrow(new SecurityException()).when(mContext)
6026                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6027                         eq("WifiService"));
6028         try {
6029             mWifiServiceImpl.unregisterTrafficStateCallback(mTrafficStateCallback);
6030             fail("expected SecurityException");
6031         } catch (SecurityException expected) {
6032         }
6033     }
6034 
6035     /**
6036      * Verify that registerTrafficStateCallback adds callback to {@link WifiTrafficPoller}.
6037      */
6038     @Test
registerTrafficStateCallbackAndVerify()6039     public void registerTrafficStateCallbackAndVerify() throws Exception {
6040         mWifiServiceImpl.registerTrafficStateCallback(mTrafficStateCallback);
6041         mLooper.dispatchAll();
6042         verify(mWifiTrafficPoller).addCallback(mTrafficStateCallback);
6043     }
6044 
6045     /**
6046      * Verify that unregisterTrafficStateCallback removes callback from {@link WifiTrafficPoller}.
6047      */
6048     @Test
unregisterTrafficStateCallbackAndVerify()6049     public void unregisterTrafficStateCallbackAndVerify() throws Exception {
6050         mWifiServiceImpl.unregisterTrafficStateCallback(mTrafficStateCallback);
6051         mLooper.dispatchAll();
6052         verify(mWifiTrafficPoller).removeCallback(mTrafficStateCallback);
6053     }
6054 
6055     /**
6056      * Verify that a call to registerNetworkRequestMatchCallback throws a SecurityException if the
6057      * caller does not have NETWORK_SETTINGS permission.
6058      */
6059     @Test
registerNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions()6060     public void registerNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() {
6061         doThrow(new SecurityException()).when(mContext)
6062                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6063                         eq("WifiService"));
6064         try {
6065             mWifiServiceImpl.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
6066             fail("expected SecurityException");
6067         } catch (SecurityException expected) {
6068         }
6069     }
6070 
6071     /**
6072      * Verify that a call to registerNetworkRequestMatchCallback throws an IllegalArgumentException
6073      * if the parameters are not provided.
6074      */
6075     @Test
6076     public void
registerNetworkRequestMatchCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()6077             registerNetworkRequestMatchCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
6078         try {
6079             mWifiServiceImpl.registerNetworkRequestMatchCallback(null);
6080             fail("expected IllegalArgumentException");
6081         } catch (IllegalArgumentException expected) {
6082         }
6083     }
6084 
6085     /**
6086      * Verify that a call to unregisterNetworkRequestMatchCallback throws a SecurityException if the
6087      * caller does not have NETWORK_SETTINGS permission.
6088      */
6089     @Test
unregisterNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions()6090     public void unregisterNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() {
6091         doThrow(new SecurityException()).when(mContext)
6092                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6093                         eq("WifiService"));
6094         try {
6095             mWifiServiceImpl.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
6096             fail("expected SecurityException");
6097         } catch (SecurityException expected) {
6098         }
6099     }
6100 
6101     /**
6102      * Verify that registerNetworkRequestMatchCallback adds callback to
6103      * {@link ClientModeManager}.
6104      */
6105     @Test
registerNetworkRequestMatchCallbackAndVerify()6106     public void registerNetworkRequestMatchCallbackAndVerify() throws Exception {
6107         mWifiServiceImpl.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
6108         mLooper.dispatchAll();
6109         verify(mWifiNetworkFactory).addCallback(mNetworkRequestMatchCallback);
6110     }
6111 
6112     /**
6113      * Verify that unregisterNetworkRequestMatchCallback removes callback from
6114      * {@link ClientModeManager}.
6115      */
6116     @Test
unregisterNetworkRequestMatchCallbackAndVerify()6117     public void unregisterNetworkRequestMatchCallbackAndVerify() throws Exception {
6118         mWifiServiceImpl.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
6119         mLooper.dispatchAll();
6120         verify(mWifiNetworkFactory).removeCallback(mNetworkRequestMatchCallback);
6121     }
6122 
6123     /**
6124      * Verify that Wifi configuration and Passpoint configuration are removed in factoryReset.
6125      */
6126     @Test
testFactoryReset()6127     public void testFactoryReset() throws Exception {
6128         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6129                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6130         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
6131         final String fqdn = "example.com";
6132         WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
6133         openNetwork.networkId = TEST_NETWORK_ID;
6134         WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork(
6135                 WifiEnterpriseConfig.Eap.TLS, WifiEnterpriseConfig.Phase2.NONE);
6136         eapNetwork.networkId = TEST_NETWORK_ID + 1;
6137         PasspointConfiguration config = new PasspointConfiguration();
6138         HomeSp homeSp = new HomeSp();
6139         homeSp.setFqdn(fqdn);
6140         config.setHomeSp(homeSp);
6141         Credential credential = new Credential();
6142         credential.setRealm("example.com");
6143         config.setCredential(credential);
6144 
6145         when(mWifiConfigManager.getSavedNetworks(anyInt()))
6146                 .thenReturn(Arrays.asList(openNetwork, eapNetwork));
6147         when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
6148                 .thenReturn(Arrays.asList(config));
6149 
6150         mLooper.startAutoDispatch();
6151         mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
6152         mLooper.stopAutoDispatchAndIgnoreExceptions();
6153 
6154         // Let the final post inside the |factoryReset| method run to completion.
6155         mLooper.dispatchAll();
6156 
6157         verify(mWifiApConfigStore).setApConfiguration(null);
6158         verify(mWifiConfigManager).removeNetwork(
6159                 openNetwork.networkId, Binder.getCallingUid(), TEST_PACKAGE_NAME);
6160         verify(mWifiConfigManager).removeNetwork(
6161                 eapNetwork.networkId, Binder.getCallingUid(), TEST_PACKAGE_NAME);
6162         verify(mWifiKeyStore).removeKeys(eapNetwork.enterpriseConfig, true);
6163         verify(mPasspointManager).removeProvider(anyInt(), anyBoolean(), eq(config.getUniqueId()),
6164                 isNull());
6165         verify(mPasspointManager).clearAnqpRequestsAndFlushCache();
6166         verify(mWifiConfigManager).clearUserTemporarilyDisabledList();
6167         verify(mWifiConfigManager).removeAllEphemeralOrPasspointConfiguredNetworks();
6168         verify(mWifiNetworkFactory).clear();
6169         verify(mWifiNetworkSuggestionsManager).clear();
6170         verify(mWifiScoreCard).clear();
6171         verify(mWifiHealthMonitor).clear();
6172         verify(mPasspointManager).getProviderConfigs(anyInt(), anyBoolean());
6173     }
6174 
6175     /**
6176      * Verify that a call to factoryReset throws a SecurityException if the caller does not have
6177      * the NETWORK_SETTINGS permission.
6178      */
6179     @Test
testFactoryResetWithoutNetworkSettingsPermission()6180     public void testFactoryResetWithoutNetworkSettingsPermission() throws Exception {
6181         doThrow(new SecurityException()).when(mContext)
6182                 .enforceCallingOrSelfPermission(eq(Manifest.permission.NETWORK_SETTINGS),
6183                         eq("WifiService"));
6184         try {
6185             mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
6186             fail();
6187         } catch (SecurityException e) {
6188         }
6189         verify(mWifiConfigManager, never()).getSavedNetworks(anyInt());
6190         verify(mPasspointManager, never()).getProviderConfigs(anyInt(), anyBoolean());
6191     }
6192 
6193     /**
6194      * Verify that add or update networks is not allowed for apps targeting Q SDK.
6195      */
6196     @Test
testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSdk()6197     public void testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSdk() throws Exception {
6198         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6199                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6200         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6201                 new NetworkUpdateResult(0));
6202 
6203         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6204         mLooper.startAutoDispatch();
6205         assertEquals(-1,
6206                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6207         mLooper.stopAutoDispatchAndIgnoreExceptions();
6208 
6209         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6210         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6211         verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
6212     }
6213 
6214     /**
6215      * Verify that add or update networks is allowed for apps targeting below Q SDK.
6216      */
6217     @Test
testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSdk()6218     public void testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSdk() throws Exception {
6219         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6220                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6221         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6222                 new NetworkUpdateResult(0));
6223         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
6224                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
6225 
6226         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6227         mLooper.startAutoDispatch();
6228         assertEquals(0,
6229                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6230         mLooper.stopAutoDispatchAndIgnoreExceptions();
6231 
6232         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6233         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6234         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6235     }
6236 
6237     /**
6238      * Verify that add or update networks is not allowed for apps targeting below Q SDK
6239      * when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6240      */
6241     @Test
testAddOrUpdateNetworkIsNotAllowedForAppsTargetingBelowQSdkWithUserRestriction()6242     public void testAddOrUpdateNetworkIsNotAllowedForAppsTargetingBelowQSdkWithUserRestriction()
6243             throws Exception {
6244         assumeTrue(SdkLevel.isAtLeastT());
6245         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6246                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6247         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6248                 new NetworkUpdateResult(0));
6249         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
6250                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
6251         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6252                 any())).thenReturn(true);
6253 
6254         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6255         mLooper.startAutoDispatch();
6256         assertEquals(-1,
6257                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6258         mLooper.stopAutoDispatchAndIgnoreExceptions();
6259 
6260         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6261         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6262         verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
6263     }
6264 
6265     /**
6266      * Verify that add or update networks is not allowed for camera app when
6267      * DISALLOW_CONFIG_WIFI user restriction is set.
6268      */
6269     @Test
testAddOrUpdateNetworkIsNotAllowedForCameraDisallowConfigWifi()6270     public void testAddOrUpdateNetworkIsNotAllowedForCameraDisallowConfigWifi() throws Exception {
6271         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6272                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6273         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6274         when(mWifiPermissionsUtil.checkCameraPermission(Binder.getCallingUid())).thenReturn(true);
6275         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6276                 .thenReturn(false);
6277         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6278                 new NetworkUpdateResult(0));
6279         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_CONFIG_WIFI),
6280                 any())).thenReturn(true);
6281 
6282         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6283         mLooper.startAutoDispatch();
6284         assertEquals(-1,
6285                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6286         mLooper.stopAutoDispatchAndIgnoreExceptions();
6287 
6288         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6289         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6290         verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
6291     }
6292 
6293     /**
6294      * Verify that add or update networks is not allowed for camera app when
6295      * DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6296      */
6297     @Test
testAddOrUpdateNetworkIsNotAllowedForCameraDisallowAddWifiConfig()6298     public void testAddOrUpdateNetworkIsNotAllowedForCameraDisallowAddWifiConfig()
6299             throws Exception {
6300         assumeTrue(SdkLevel.isAtLeastT());
6301         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6302                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6303         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6304         when(mWifiPermissionsUtil.checkCameraPermission(Binder.getCallingUid())).thenReturn(true);
6305         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6306                 .thenReturn(false);
6307         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6308                 new NetworkUpdateResult(0));
6309         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6310                 any())).thenReturn(true);
6311 
6312         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6313         mLooper.startAutoDispatch();
6314         assertEquals(-1,
6315                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6316         mLooper.stopAutoDispatchAndIgnoreExceptions();
6317 
6318         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6319         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6320         verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
6321     }
6322 
6323     /**
6324      * Verify that add or update networks is allowed for settings app.
6325      */
6326     @Test
testAddOrUpdateNetworkIsAllowedForSettingsApp()6327     public void testAddOrUpdateNetworkIsAllowedForSettingsApp() throws Exception {
6328         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6329                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6330         mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
6331         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6332                 new NetworkUpdateResult(0));
6333 
6334         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6335         mLooper.startAutoDispatch();
6336         assertEquals(0,
6337                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6338         mLooper.stopAutoDispatchAndIgnoreExceptions();
6339 
6340         // Ensure that we don't check for change permission.
6341         verify(mContext, never()).enforceCallingOrSelfPermission(
6342                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
6343         verify(mAppOpsManager, never()).noteOp(
6344                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6345         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6346         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6347     }
6348 
6349     /**
6350      * Verify that add or update networks is allowed for system apps.
6351      */
6352     @Test
testAddOrUpdateNetworkIsAllowedForSystemApp()6353     public void testAddOrUpdateNetworkIsAllowedForSystemApp() throws Exception {
6354         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6355                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6356         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6357         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6358                 new NetworkUpdateResult(0));
6359 
6360         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6361         mLooper.startAutoDispatch();
6362         assertEquals(0,
6363                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6364         mLooper.stopAutoDispatchAndIgnoreExceptions();
6365 
6366         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6367         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6368         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6369     }
6370 
6371     /**
6372      * Verify that add or update networks is allowed for apps holding system alert permission.
6373      */
6374     @Test
testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission()6375     public void testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission() throws Exception {
6376         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6377                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6378         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6379                 new NetworkUpdateResult(0));
6380 
6381         // Verify caller fails to add network as Guest user.
6382         when(mWifiPermissionsUtil.checkSystemAlertWindowPermission(
6383                 Process.myUid(), TEST_PACKAGE_NAME)).thenReturn(true);
6384         when(mWifiPermissionsUtil.isGuestUser()).thenReturn(true);
6385         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6386         mLooper.startAutoDispatch();
6387         assertEquals(-1,
6388                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6389 
6390         // Verify caller successfully add network when not a Guest user.
6391         when(mWifiPermissionsUtil.isGuestUser()).thenReturn(false);
6392         assertEquals(0,
6393                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6394         mLooper.stopAutoDispatchAndIgnoreExceptions();
6395 
6396         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6397         verify(mWifiPermissionsUtil, times(2))
6398                 .checkSystemAlertWindowPermission(anyInt(), anyString());
6399         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6400         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6401     }
6402 
6403     /**
6404      * Verify that add or update networks is allowed for DeviceOwner app.
6405      */
6406     @Test
testAddOrUpdateNetworkIsAllowedForDOApp()6407     public void testAddOrUpdateNetworkIsAllowedForDOApp() throws Exception {
6408         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6409                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6410         when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6411                 .thenReturn(true);
6412         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6413                 new NetworkUpdateResult(0));
6414         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6415                 .thenReturn(true);
6416 
6417         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6418         mLooper.startAutoDispatch();
6419         assertEquals(0,
6420                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6421         mLooper.stopAutoDispatchAndIgnoreExceptions();
6422 
6423         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6424         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6425         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6426     }
6427 
6428     /**
6429      * Verify that add or update networks is allowed for ProfileOwner app.
6430      */
6431     @Test
testAddOrUpdateNetworkIsAllowedForPOApp()6432     public void testAddOrUpdateNetworkIsAllowedForPOApp() throws Exception {
6433         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6434                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6435         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6436                 .thenReturn(true);
6437         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6438                 new NetworkUpdateResult(0));
6439         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6440                 .thenReturn(true);
6441 
6442         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6443         mLooper.startAutoDispatch();
6444         assertEquals(0,
6445                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6446         mLooper.stopAutoDispatchAndIgnoreExceptions();
6447 
6448         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6449         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6450         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6451     }
6452 
6453     /**
6454      * Verify that add or update networks is allowed for an admin app.
6455      */
6456     @Test
testAddOrUpdateNetworkIsAllowedForAdminApp()6457     public void testAddOrUpdateNetworkIsAllowedForAdminApp() throws Exception {
6458         assumeTrue(SdkLevel.isAtLeastT());
6459         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6460                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6461         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6462                 .thenReturn(true);
6463         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
6464                 new NetworkUpdateResult(0));
6465 
6466         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6467         mLooper.startAutoDispatch();
6468         assertEquals(0,
6469                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
6470         mLooper.stopAutoDispatchAndIgnoreExceptions();
6471 
6472         verifyCheckChangePermission(TEST_PACKAGE_NAME);
6473         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6474         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6475     }
6476 
verifyAddOrUpdateNetworkPrivilegedDoesNotThrowException()6477     private void verifyAddOrUpdateNetworkPrivilegedDoesNotThrowException() {
6478         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6479         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
6480                 .thenReturn(new NetworkUpdateResult(0));
6481         mLooper.startAutoDispatch();
6482         mWifiServiceImpl.addOrUpdateNetworkPrivileged(config, TEST_PACKAGE_NAME);
6483         mLooper.stopAutoDispatchAndIgnoreExceptions();
6484 
6485         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
6486         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
6487     }
6488 
6489     /**
6490      * Verify that addOrUpdateNetworkPrivileged throws a SecurityException if the calling app
6491      * has no permissions.
6492      */
6493     @Test
testAddOrUpdateNetworkPrivilegedNotAllowedForNormalApps()6494     public void testAddOrUpdateNetworkPrivilegedNotAllowedForNormalApps() throws Exception {
6495         try {
6496             WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6497             mWifiServiceImpl.addOrUpdateNetworkPrivileged(config, TEST_PACKAGE_NAME);
6498             fail("Expected SecurityException for apps without permission");
6499         } catch (SecurityException e) {
6500         }
6501     }
6502 
6503     /**
6504      * Verify that a privileged app with NETWORK_SETTINGS permission is allowed to call
6505      * addOrUpdateNetworkPrivileged.
6506      */
6507     @Test
testAddOrUpdateNetworkPrivilegedIsAllowedForPrivilegedApp()6508     public void testAddOrUpdateNetworkPrivilegedIsAllowedForPrivilegedApp() throws Exception {
6509         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6510                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6511         verifyAddOrUpdateNetworkPrivilegedDoesNotThrowException();
6512     }
6513 
6514     /**
6515      * Verify that a system app is allowed to call addOrUpdateNetworkPrivileged.
6516      */
6517     @Test
testAddOrUpdateNetworkPrivilegedIsAllowedForSystemApp()6518     public void testAddOrUpdateNetworkPrivilegedIsAllowedForSystemApp() throws Exception {
6519         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6520         verifyAddOrUpdateNetworkPrivilegedDoesNotThrowException();
6521     }
6522 
6523     /**
6524      * Verify that an admin app is allowed to call addOrUpdateNetworkPrivileged.
6525      */
6526     @Test
testAddOrUpdateNetworkPrivilegedIsAllowedForAdminApp()6527     public void testAddOrUpdateNetworkPrivilegedIsAllowedForAdminApp() throws Exception {
6528         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6529                 .thenReturn(true);
6530         verifyAddOrUpdateNetworkPrivilegedDoesNotThrowException();
6531     }
6532 
6533     /**
6534      * Verify the proper status code is returned when addOrUpdateNetworkPrivileged failed due to
6535      * a failure in WifiConfigManager.addOrUpdateNetwork().
6536      */
6537     @Test
testAddOrUpdateNetworkInvalidConfiguration()6538     public void testAddOrUpdateNetworkInvalidConfiguration() throws Exception {
6539         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6540         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
6541                 .thenReturn(new NetworkUpdateResult(-1));
6542         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6543         mLooper.startAutoDispatch();
6544         WifiManager.AddNetworkResult result = mWifiServiceImpl.addOrUpdateNetworkPrivileged(
6545                 config, TEST_PACKAGE_NAME);
6546         mLooper.stopAutoDispatchAndIgnoreExceptions();
6547 
6548         assertEquals(WifiManager.AddNetworkResult.STATUS_ADD_WIFI_CONFIG_FAILURE,
6549                 result.statusCode);
6550         assertEquals(-1, result.networkId);
6551     }
6552 
6553     /**
6554      * Verify that enableNetwork is allowed for privileged Apps
6555      */
6556     @Test
testEnableNetworkWithDisableOthersAllowedForPrivilegedApps()6557     public void testEnableNetworkWithDisableOthersAllowedForPrivilegedApps() throws Exception {
6558         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6559                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6560         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6561                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6562 
6563         doAnswer(new AnswerWithArguments() {
6564             public void answer(NetworkUpdateResult result, ActionListenerWrapper callback,
6565                     int callingUid, String packageName) {
6566                 callback.sendSuccess(); // return success
6567             }
6568         }).when(mConnectHelper).connectToNetwork(
6569                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
6570 
6571         mLooper.startAutoDispatch();
6572         assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
6573         mLooper.stopAutoDispatch();
6574 
6575         verify(mConnectHelper).connectToNetwork(
6576                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
6577         verify(mWifiMetrics).incrementNumEnableNetworkCalls();
6578     }
6579 
6580     /**
6581      * Verify that enableNetwork (with disableOthers=true) is allowed for Apps targeting a SDK
6582      * version less than Q
6583      */
6584     @Test
testEnabledNetworkWithDisableOthersAllowedForAppsTargetingBelowQSdk()6585     public void testEnabledNetworkWithDisableOthersAllowedForAppsTargetingBelowQSdk()
6586             throws Exception {
6587         mLooper.dispatchAll();
6588         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6589                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6590         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
6591                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
6592 
6593         doAnswer(new AnswerWithArguments() {
6594             public void answer(NetworkUpdateResult result, ActionListenerWrapper callback,
6595                     int callingUid, String packageName) {
6596                 callback.sendSuccess(); // return success
6597             }
6598         }).when(mConnectHelper).connectToNetwork(
6599                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
6600 
6601         mLooper.startAutoDispatch();
6602         assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
6603         mLooper.stopAutoDispatch();
6604 
6605         verify(mConnectHelper).connectToNetwork(
6606                 eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
6607         verify(mWifiMetrics).incrementNumEnableNetworkCalls();
6608     }
6609 
6610     /**
6611      * Verify that enableNetwork (with disableOthers=false) is allowed for Apps targeting a SDK
6612      * version less than Q
6613      */
6614     @Test
testEnabledNetworkWithoutDisableOthersAllowedForAppsTargetingBelowQSdk()6615     public void testEnabledNetworkWithoutDisableOthersAllowedForAppsTargetingBelowQSdk()
6616             throws Exception {
6617         mLooper.dispatchAll();
6618         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6619                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6620         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
6621                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
6622 
6623         when(mWifiConfigManager.enableNetwork(anyInt(), anyBoolean(), anyInt(), anyString()))
6624                 .thenReturn(true);
6625         mLooper.startAutoDispatch();
6626         assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, false, TEST_PACKAGE_NAME));
6627         mLooper.stopAutoDispatchAndIgnoreExceptions();
6628         verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false),
6629                 eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME));
6630         verify(mWifiMetrics).incrementNumEnableNetworkCalls();
6631     }
6632 
6633     /**
6634      * Verify that enableNetwork is not allowed for Apps targeting Q SDK
6635      */
6636     @Test
testEnableNetworkNotAllowedForAppsTargetingQ()6637     public void testEnableNetworkNotAllowedForAppsTargetingQ() throws Exception {
6638         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6639                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6640 
6641         mLooper.startAutoDispatch();
6642         mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
6643         mLooper.stopAutoDispatchAndIgnoreExceptions();
6644 
6645         verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
6646         verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
6647     }
6648 
6649     /**
6650      * Verify that enableNetwork is not allowed for admin restricted network
6651      */
6652     @Test
testEnableNetworkNotAllowedForAdminRestrictedNetwork()6653     public void testEnableNetworkNotAllowedForAdminRestrictedNetwork() throws Exception {
6654         assumeTrue(SdkLevel.isAtLeastT());
6655         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
6656                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
6657         when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE_NAME, Process.myUid())).thenReturn(true);
6658         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
6659         when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
6660         when(mWifiPermissionsUtil.isAdminRestrictedNetwork(config)).thenReturn(true);
6661 
6662         mLooper.startAutoDispatch();
6663         mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
6664         mLooper.stopAutoDispatchAndIgnoreExceptions();
6665 
6666         verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
6667         verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
6668     }
6669 
6670     /**
6671      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
6672      * suggestions.
6673      */
6674     @Test
testAddNetworkSuggestions()6675     public void testAddNetworkSuggestions() {
6676         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6677                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6678         mLooper.startAutoDispatch();
6679         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6680                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6681                         TEST_FEATURE_ID));
6682         mLooper.stopAutoDispatchAndIgnoreExceptions();
6683 
6684         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6685                 nullable(String.class))).thenReturn(
6686                 WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE);
6687         mLooper.startAutoDispatch();
6688         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
6689                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6690                         TEST_FEATURE_ID));
6691         mLooper.stopAutoDispatchAndIgnoreExceptions();
6692 
6693         verify(mWifiNetworkSuggestionsManager, times(2)).add(
6694                 any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6695     }
6696 
6697     /**
6698      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
6699      * suggestions for carrier app when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6700      */
6701     @Test
testAddNetworkSuggestionsIsAllowedForCarrierAppWithUserRestriction()6702     public void testAddNetworkSuggestionsIsAllowedForCarrierAppWithUserRestriction() {
6703         assumeTrue(SdkLevel.isAtLeastT());
6704         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6705                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6706         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6707                 any())).thenReturn(true);
6708         when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(anyString())).thenReturn(
6709                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
6710 
6711         mLooper.startAutoDispatch();
6712         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6713                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6714                         TEST_FEATURE_ID));
6715         mLooper.stopAutoDispatchAndIgnoreExceptions();
6716 
6717         verify(mWifiNetworkSuggestionsManager).add(
6718                 any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6719     }
6720 
6721     /**
6722      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
6723      * suggestions for privileged app when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6724      */
6725     @Test
testAddNetworkSuggestionsIsAllowedForPrivilegedAppWithUserRestriction()6726     public void testAddNetworkSuggestionsIsAllowedForPrivilegedAppWithUserRestriction() {
6727         assumeTrue(SdkLevel.isAtLeastT());
6728         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6729                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6730         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6731                 any())).thenReturn(true);
6732         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6733                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6734 
6735         mLooper.startAutoDispatch();
6736         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6737                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6738                         TEST_FEATURE_ID));
6739         mLooper.stopAutoDispatchAndIgnoreExceptions();
6740 
6741         verify(mWifiNetworkSuggestionsManager).add(
6742                 any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6743     }
6744 
6745     /**
6746      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
6747      * suggestions for system app when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6748      */
6749     @Test
testAddNetworkSuggestionsIsAllowedForSystemAppWithUserRestriction()6750     public void testAddNetworkSuggestionsIsAllowedForSystemAppWithUserRestriction() {
6751         assumeTrue(SdkLevel.isAtLeastT());
6752         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6753                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6754         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6755                 any())).thenReturn(true);
6756         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
6757 
6758         mLooper.startAutoDispatch();
6759         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6760                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6761                         TEST_FEATURE_ID));
6762         mLooper.stopAutoDispatchAndIgnoreExceptions();
6763 
6764         verify(mWifiNetworkSuggestionsManager).add(
6765                 any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6766     }
6767 
6768     /**
6769      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
6770      * suggestions for admin app when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6771      */
6772     @Test
testAddNetworkSuggestionsIsAllowedForAdminAppWithUserRestriction()6773     public void testAddNetworkSuggestionsIsAllowedForAdminAppWithUserRestriction() {
6774         assumeTrue(SdkLevel.isAtLeastT());
6775         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6776                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6777         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6778                 any())).thenReturn(true);
6779         when(mWifiPermissionsUtil.isAdmin(anyInt(), anyString())).thenReturn(true);
6780 
6781         mLooper.startAutoDispatch();
6782         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6783                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6784                         TEST_FEATURE_ID));
6785         mLooper.stopAutoDispatchAndIgnoreExceptions();
6786 
6787         verify(mWifiNetworkSuggestionsManager).add(
6788                 any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6789     }
6790 
6791     /**
6792      * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to add network
6793      * suggestions for normal app when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
6794      */
6795     @Test
testAddNetworkSuggestionsIsNotAllowedForNormalAppWithUserRestriction()6796     public void testAddNetworkSuggestionsIsNotAllowedForNormalAppWithUserRestriction() {
6797         assumeTrue(SdkLevel.isAtLeastT());
6798         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
6799                 nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6800         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
6801                 any())).thenReturn(true);
6802 
6803         mLooper.startAutoDispatch();
6804         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_RESTRICTED_BY_ADMIN,
6805                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6806                         TEST_FEATURE_ID));
6807         mLooper.stopAutoDispatchAndIgnoreExceptions();
6808 
6809         verify(mWifiNetworkSuggestionsManager, never()).add(any(), eq(Binder.getCallingUid()),
6810                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6811     }
6812 
6813     /**
6814      * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to add network
6815      * suggestions when the looper sync call times out.
6816      */
6817     @Test
testAddNetworkSuggestionsFailureInRunWithScissors()6818     public void testAddNetworkSuggestionsFailureInRunWithScissors() {
6819         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
6820 
6821         mLooper.startAutoDispatch();
6822         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
6823                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6824                         TEST_FEATURE_ID));
6825         mLooper.stopAutoDispatchAndIgnoreExceptions();
6826 
6827         verify(mWifiNetworkSuggestionsManager, never()).add(any(), eq(Binder.getCallingUid()),
6828                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID));
6829     }
6830 
6831     /**
6832      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to remove network
6833      * suggestions.
6834      */
6835     @Test
testRemoveNetworkSuggestions()6836     public void testRemoveNetworkSuggestions() {
6837         when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString(), anyInt()))
6838                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID);
6839         mLooper.startAutoDispatch();
6840         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
6841                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6842                         ACTION_REMOVE_SUGGESTION_DISCONNECT));
6843         mLooper.stopAutoDispatchAndIgnoreExceptions();
6844 
6845         when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString(),
6846                 anyInt()))
6847                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
6848         mLooper.startAutoDispatch();
6849         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
6850                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6851                         ACTION_REMOVE_SUGGESTION_DISCONNECT));
6852         mLooper.stopAutoDispatchAndIgnoreExceptions();
6853 
6854         verify(mWifiNetworkSuggestionsManager, times(2)).remove(any(), anyInt(),
6855                 eq(TEST_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
6856     }
6857 
6858     /**
6859      * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to remove network
6860      * suggestions when the looper sync call times out.
6861      */
6862     @Test
testRemoveNetworkSuggestionsFailureInRunWithScissors()6863     public void testRemoveNetworkSuggestionsFailureInRunWithScissors() {
6864         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
6865 
6866         mLooper.startAutoDispatch();
6867         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
6868                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
6869                 ACTION_REMOVE_SUGGESTION_DISCONNECT));
6870         mLooper.stopAutoDispatchAndIgnoreExceptions();
6871 
6872         verify(mWifiNetworkSuggestionsManager, never()).remove(any(), anyInt(),
6873                 eq(TEST_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
6874     }
6875 
6876     /**
6877      * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to remove network
6878      * suggestions when the action is invalid.
6879      */
6880     @Test
testRemoveNetworkSuggestionsFailureWithInvalidAction()6881     public void testRemoveNetworkSuggestionsFailureWithInvalidAction() {
6882         mLooper.startAutoDispatch();
6883         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
6884                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME, 0));
6885         mLooper.stopAutoDispatchAndIgnoreExceptions();
6886         verify(mWifiNetworkSuggestionsManager, never()).remove(any(), anyInt(),
6887                 eq(TEST_PACKAGE_NAME), anyInt());
6888     }
6889 
6890     @Test(expected = SecurityException.class)
testRemoveNonCallerConfiguredNetworks_NormalAppCaller_ThrowsException()6891     public void testRemoveNonCallerConfiguredNetworks_NormalAppCaller_ThrowsException() {
6892         mWifiServiceImpl.removeNonCallerConfiguredNetworks(TEST_PACKAGE_NAME);
6893     }
6894 
6895     @Test(expected = SecurityException.class)
testRemoveNonCallerConfiguredNetworks_CallerIsProfileOwner_ThrowsException()6896     public void testRemoveNonCallerConfiguredNetworks_CallerIsProfileOwner_ThrowsException() {
6897         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
6898                 .thenReturn(true);
6899         mWifiServiceImpl.removeNonCallerConfiguredNetworks(TEST_PACKAGE_NAME);
6900     }
6901 
6902     @Test
testRemoveNonCallerConfiguredNetworks_NetworksRemoved()6903     public void testRemoveNonCallerConfiguredNetworks_NetworksRemoved() {
6904         final int callerUid = Binder.getCallingUid();
6905         when(mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(
6906                 Binder.getCallingUid(), TEST_PACKAGE_NAME)).thenReturn(true);
6907 
6908         mLooper.startAutoDispatch();
6909         mWifiServiceImpl.removeNonCallerConfiguredNetworks(TEST_PACKAGE_NAME);
6910         mLooper.stopAutoDispatchAndIgnoreExceptions();
6911 
6912         verify(mWifiConfigManager).removeNonCallerConfiguredNetwork(eq(callerUid));
6913     }
6914 
6915     /**
6916      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to get network
6917      * suggestions.
6918      */
6919     @Test
testGetNetworkSuggestions()6920     public void testGetNetworkSuggestions() {
6921         List<WifiNetworkSuggestion> testList = new ArrayList<>();
6922         when(mWifiNetworkSuggestionsManager.get(anyString(), anyInt())).thenReturn(testList);
6923         mLooper.startAutoDispatch();
6924         assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME));
6925         mLooper.stopAutoDispatchAndIgnoreExceptions();
6926 
6927         verify(mWifiNetworkSuggestionsManager).get(eq(TEST_PACKAGE_NAME), anyInt());
6928     }
6929 
6930     /**
6931      * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to get network
6932      * suggestions when the looper sync call times out.
6933      */
6934     @Test
testGetNetworkSuggestionsFailureInRunWithScissors()6935     public void testGetNetworkSuggestionsFailureInRunWithScissors() {
6936         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
6937 
6938         mLooper.startAutoDispatch();
6939         assertTrue(mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).isEmpty());
6940         mLooper.stopAutoDispatchAndIgnoreExceptions();
6941 
6942         verify(mWifiNetworkSuggestionsManager, never()).get(eq(TEST_PACKAGE_NAME), anyInt());
6943     }
6944 
6945     /**
6946      * Verify that if the caller has NETWORK_SETTINGS permission, then it can invoke
6947      * {@link WifiManager#disableEphemeralNetwork(String)}.
6948      */
6949     @Test
testDisableEphemeralNetworkWithNetworkSettingsPerm()6950     public void testDisableEphemeralNetworkWithNetworkSettingsPerm() throws Exception {
6951         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6952                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
6953         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
6954         mLooper.dispatchAll();
6955         verify(mWifiConfigManager).userTemporarilyDisabledNetwork(anyString(), anyInt());
6956     }
6957 
6958     /**
6959      * Verify that if the caller does not have NETWORK_SETTINGS permission, then it cannot invoke
6960      * {@link WifiManager#disableEphemeralNetwork(String)}.
6961      */
6962     @Test
testDisableEphemeralNetworkWithoutNetworkSettingsPerm()6963     public void testDisableEphemeralNetworkWithoutNetworkSettingsPerm() throws Exception {
6964         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
6965                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
6966         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
6967         mLooper.dispatchAll();
6968         verify(mWifiConfigManager, never()).userTemporarilyDisabledNetwork(anyString(), anyInt());
6969     }
6970 
6971     /**
6972      * Verify getting the factory MAC address.
6973      */
6974     @Test
testGetFactoryMacAddresses()6975     public void testGetFactoryMacAddresses() throws Exception {
6976         when(mClientModeManager.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
6977         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
6978         mLooper.startAutoDispatch();
6979         final String[] factoryMacs = mWifiServiceImpl.getFactoryMacAddresses();
6980         mLooper.stopAutoDispatchAndIgnoreExceptions();
6981         assertEquals(1, factoryMacs.length);
6982         assertEquals(TEST_FACTORY_MAC, factoryMacs[0]);
6983         verify(mClientModeManager).getFactoryMacAddress();
6984     }
6985 
6986     /**
6987      * Verify getting the factory MAC address returns null when posting the runnable to handler
6988      * fails.
6989      */
6990     @Test
testGetFactoryMacAddressesPostFail()6991     public void testGetFactoryMacAddressesPostFail() throws Exception {
6992         mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
6993 
6994         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
6995         mLooper.startAutoDispatch();
6996         assertArrayEquals(new String[0], mWifiServiceImpl.getFactoryMacAddresses());
6997         mLooper.stopAutoDispatchAndIgnoreExceptions();
6998         verify(mClientModeManager, never()).getFactoryMacAddress();
6999     }
7000 
7001     /**
7002      * Verify getting the factory MAC address returns null when the lower layers fail.
7003      */
7004     @Test
testGetFactoryMacAddressesFail()7005     public void testGetFactoryMacAddressesFail() throws Exception {
7006         when(mClientModeManager.getFactoryMacAddress()).thenReturn(null);
7007         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
7008         mLooper.startAutoDispatch();
7009         assertArrayEquals(new String[0], mWifiServiceImpl.getFactoryMacAddresses());
7010         mLooper.stopAutoDispatchAndIgnoreExceptions();
7011         verify(mClientModeManager).getFactoryMacAddress();
7012     }
7013 
7014     /**
7015      * Verify getting the factory MAC address throws a SecurityException if the calling app
7016      * doesn't have NETWORK_SETTINGS permission.
7017      */
7018     @Test
testGetFactoryMacAddressesFailNoNetworkSettingsPermission()7019     public void testGetFactoryMacAddressesFailNoNetworkSettingsPermission() throws Exception {
7020         when(mClientModeManager.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
7021         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
7022         try {
7023             mLooper.startAutoDispatch();
7024             mWifiServiceImpl.getFactoryMacAddresses();
7025             mLooper.stopAutoDispatchAndIgnoreExceptions();
7026             fail();
7027         } catch (SecurityException e) {
7028             assertTrue("Exception message should contain 'factory MAC'",
7029                     e.toString().contains("factory MAC"));
7030         }
7031     }
7032 
7033     /**
7034      * Verify that a call to setDeviceMobilityState throws a SecurityException if the
7035      * caller does not have WIFI_SET_DEVICE_MOBILITY_STATE permission.
7036      */
7037     @Test(expected = SecurityException.class)
setDeviceMobilityStateThrowsSecurityExceptionOnMissingPermissions()7038     public void setDeviceMobilityStateThrowsSecurityExceptionOnMissingPermissions() {
7039         doThrow(new SecurityException()).when(mContext)
7040                 .enforceCallingOrSelfPermission(
7041                         eq(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE),
7042                         eq("WifiService"));
7043         mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7044     }
7045 
7046     /**
7047      * Verifies that setDeviceMobilityState runs on a separate handler thread.
7048      */
7049     @Test
setDeviceMobilityStateRunsOnHandler()7050     public void setDeviceMobilityStateRunsOnHandler() {
7051         mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7052         verify(mWifiConnectivityManager, never())
7053                 .setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7054         verify(mWifiHealthMonitor, never())
7055                 .setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7056         verify(mWifiDataStall, never())
7057                 .setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7058         mLooper.dispatchAll();
7059         verify(mWifiConnectivityManager).setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7060         verify(mWifiHealthMonitor).setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7061         verify(mWifiDataStall).setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
7062     }
7063 
7064     /**
7065      * Verify that a call to addOnWifiUsabilityStatsListener throws a SecurityException if
7066      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
7067      */
7068     @Test
testAddStatsListenerThrowsSecurityExceptionOnMissingPermissions()7069     public void testAddStatsListenerThrowsSecurityExceptionOnMissingPermissions() {
7070         doThrow(new SecurityException()).when(mContext)
7071                 .enforceCallingOrSelfPermission(
7072                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
7073                         eq("WifiService"));
7074         try {
7075             mWifiServiceImpl.addOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
7076             fail("expected SecurityException");
7077         } catch (SecurityException expected) {
7078         }
7079     }
7080 
7081     /**
7082      * Verify that a call to addOnWifiUsabilityStatsListener throws an IllegalArgumentException
7083      * if the parameters are not provided.
7084      */
7085     @Test
testAddStatsListenerThrowsIllegalArgumentExceptionOnInvalidArguments()7086     public void testAddStatsListenerThrowsIllegalArgumentExceptionOnInvalidArguments() {
7087         try {
7088             mWifiServiceImpl.addOnWifiUsabilityStatsListener(null);
7089             fail("expected IllegalArgumentException");
7090         } catch (IllegalArgumentException expected) {
7091         }
7092     }
7093 
7094     /**
7095      * Verify that a call to removeOnWifiUsabilityStatsListener throws a SecurityException if
7096      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
7097      */
7098     @Test
testRemoveStatsListenerThrowsSecurityExceptionOnMissingPermissions()7099     public void testRemoveStatsListenerThrowsSecurityExceptionOnMissingPermissions() {
7100         doThrow(new SecurityException()).when(mContext)
7101                 .enforceCallingOrSelfPermission(
7102                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
7103                         eq("WifiService"));
7104         try {
7105             mWifiServiceImpl.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
7106             fail("expected SecurityException");
7107         } catch (SecurityException expected) {
7108         }
7109     }
7110 
7111     /**
7112      * Verify that addOnWifiUsabilityStatsListener adds listener to {@link WifiMetrics}.
7113      */
7114     @Test
testAddOnWifiUsabilityStatsListenerAndVerify()7115     public void testAddOnWifiUsabilityStatsListenerAndVerify() throws Exception {
7116         mWifiServiceImpl.addOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
7117         mLooper.dispatchAll();
7118         verify(mWifiMetrics).addOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
7119     }
7120 
7121     /**
7122      * Verify that removeOnWifiUsabilityStatsListener removes listener from
7123      * {@link WifiMetrics}.
7124      */
7125     @Test
testRemoveOnWifiUsabilityStatsListenerAndVerify()7126     public void testRemoveOnWifiUsabilityStatsListenerAndVerify() throws Exception {
7127         mWifiServiceImpl.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
7128         mLooper.dispatchAll();
7129         verify(mWifiMetrics).removeOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
7130     }
7131 
7132     /**
7133      * Verify that a call to updateWifiUsabilityScore throws a SecurityException if the
7134      * caller does not have UPDATE_WIFI_USABILITY_SCORE permission.
7135      */
7136     @Test
testUpdateWifiUsabilityScoreThrowsSecurityExceptionOnMissingPermissions()7137     public void testUpdateWifiUsabilityScoreThrowsSecurityExceptionOnMissingPermissions() {
7138         doThrow(new SecurityException()).when(mContext)
7139                 .enforceCallingOrSelfPermission(
7140                 eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
7141                 eq("WifiService"));
7142         try {
7143             mWifiServiceImpl.updateWifiUsabilityScore(anyInt(), anyInt(), 15);
7144             fail("expected SecurityException");
7145         } catch (SecurityException expected) {
7146         }
7147     }
7148 
7149     /**
7150      * Verify that mClientModeManager in WifiServiceImpl is being updated on Wifi usability score
7151      * update event.
7152      */
7153     @Test
testWifiUsabilityScoreUpdateAfterScoreEvent()7154     public void testWifiUsabilityScoreUpdateAfterScoreEvent() {
7155         mWifiServiceImpl.updateWifiUsabilityScore(5, 10, 15);
7156         mLooper.dispatchAll();
7157         verify(mWifiMetrics).incrementWifiUsabilityScoreCount(WIFI_IFACE_NAME, 5, 10, 15);
7158     }
7159 
startLohsAndTethering(boolean isApConcurrencySupported)7160     private void startLohsAndTethering(boolean isApConcurrencySupported) throws Exception {
7161         // initialization
7162         when(mActiveModeWarden.canRequestMoreSoftApManagers(
7163                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME))))
7164                 .thenReturn(isApConcurrencySupported);
7165         // For these tests, always use distinct interface names for LOHS and tethered.
7166         mLohsInterfaceName = WIFI_IFACE_NAME2;
7167 
7168         setupLocalOnlyHotspot();
7169         reset(mActiveModeWarden);
7170 
7171         when(mActiveModeWarden.canRequestMoreSoftApManagers(
7172                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME))))
7173                 .thenReturn(isApConcurrencySupported);
7174 
7175         // start tethering
7176         mLooper.startAutoDispatch();
7177         boolean tetheringResult = mWifiServiceImpl.startSoftAp(null, TEST_PACKAGE_NAME);
7178         mLooper.stopAutoDispatchAndIgnoreExceptions();
7179         assertTrue(tetheringResult);
7180         verify(mActiveModeWarden).startSoftAp(any(),
7181                 eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
7182         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
7183         mLooper.dispatchAll();
7184     }
7185 
7186     /**
7187      * Verify LOHS gets stopped when trying to start tethering concurrently on devices that
7188      * doesn't support dual AP operation.
7189      */
7190     @Test
testStartLohsAndTethering1AP()7191     public void testStartLohsAndTethering1AP() throws Exception {
7192         startLohsAndTethering(false);
7193 
7194         // verify LOHS got stopped
7195         verify(mLohsCallback).onHotspotFailed(anyInt());
7196         verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
7197     }
7198 
7199     /**
7200      * Verify LOHS doesn't get stopped when trying to start tethering concurrently on devices
7201      * that does support dual AP operation.
7202      */
7203     @Test
testStartLohsAndTethering2AP()7204     public void testStartLohsAndTethering2AP() throws Exception {
7205         startLohsAndTethering(true);
7206 
7207         // verify LOHS didn't get stopped
7208         verifyZeroInteractions(ignoreStubs(mLohsCallback));
7209         verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
7210     }
7211 
7212     /**
7213      * Verify that the call to startDppAsConfiguratorInitiator throws a security exception when the
7214      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
7215      */
7216     @Test(expected = SecurityException.class)
testStartDppAsConfiguratorInitiatorWithoutPermissions()7217     public void testStartDppAsConfiguratorInitiatorWithoutPermissions() {
7218         mWifiServiceImpl.startDppAsConfiguratorInitiator(mAppBinder, TEST_PACKAGE_NAME, DPP_URI,
7219                 1, 1, mDppCallback);
7220     }
7221 
7222     /**
7223      * Verify that the call to startDppAsEnrolleeInitiator throws a security exception when the
7224      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
7225      */
7226     @Test(expected = SecurityException.class)
testStartDppAsEnrolleeInitiatorWithoutPermissions()7227     public void testStartDppAsEnrolleeInitiatorWithoutPermissions() {
7228         mWifiServiceImpl.startDppAsEnrolleeInitiator(mAppBinder, DPP_URI, mDppCallback);
7229     }
7230 
7231     /**
7232      * Verify that the call to startDppAsEnrolleeResponder throws a security exception when the
7233      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
7234      */
7235     @Test(expected = SecurityException.class)
testStartDppAsEnrolleeResponderWithoutPermissions()7236     public void testStartDppAsEnrolleeResponderWithoutPermissions() {
7237         assumeTrue(SdkLevel.isAtLeastS());
7238         mWifiServiceImpl.startDppAsEnrolleeResponder(mAppBinder, DPP_PRODUCT_INFO,
7239                 EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1, mDppCallback);
7240     }
7241 
7242     /**
7243      * Verify that a call to StartDppAsEnrolleeResponder throws an IllegalArgumentException
7244      * if the deviceInfo length exceeds the max allowed length.
7245      */
7246     @Test(expected = SecurityException.class)
testStartDppAsEnrolleeResponderThrowsIllegalArgumentExceptionOnDeviceInfoMaxLen()7247     public void testStartDppAsEnrolleeResponderThrowsIllegalArgumentExceptionOnDeviceInfoMaxLen() {
7248         assumeTrue(SdkLevel.isAtLeastS());
7249         try {
7250             StringBuilder sb = new StringBuilder();
7251             sb.append(Strings.repeat("a",
7252                     WifiManager.getEasyConnectMaxAllowedResponderDeviceInfoLength() + 2));
7253             String deviceInfo = sb.toString();
7254             mWifiServiceImpl.startDppAsEnrolleeResponder(mAppBinder, deviceInfo,
7255                     EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1, mDppCallback);
7256             fail("expected IllegalArgumentException");
7257         } catch (IllegalArgumentException expected) {
7258         }
7259     }
7260 
7261     /**
7262      * Verify that a call to StartDppAsEnrolleeResponder throws an IllegalArgumentException
7263      * if the deviceInfo contains characters which are not allowed as per spec (For example
7264      * semicolon)
7265      */
7266     @Test(expected = SecurityException.class)
testStartDppAsEnrolleeResponderThrowsIllegalArgumentExceptionOnWrongDeviceInfo()7267     public void testStartDppAsEnrolleeResponderThrowsIllegalArgumentExceptionOnWrongDeviceInfo() {
7268         assumeTrue(SdkLevel.isAtLeastS());
7269         try {
7270             mWifiServiceImpl.startDppAsEnrolleeResponder(mAppBinder, "DPP;TESTER",
7271                     EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1, mDppCallback);
7272             fail("expected IllegalArgumentException");
7273         } catch (IllegalArgumentException expected) {
7274         }
7275     }
7276 
7277     /**
7278      * Verify that the call to stopDppSession throws a security exception when the
7279      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
7280      */
7281     @Test(expected = SecurityException.class)
testStopDppSessionWithoutPermissions()7282     public void testStopDppSessionWithoutPermissions() {
7283         try {
7284             mWifiServiceImpl.stopDppSession();
7285         } catch (RemoteException e) {
7286         }
7287     }
7288 
7289     /**
7290      * Verifies that configs can be removed.
7291      */
7292     @Test
testRemoveNetworkIsAllowedForAppsTargetingBelowQSdk()7293     public void testRemoveNetworkIsAllowedForAppsTargetingBelowQSdk() {
7294         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7295                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7296         when(mWifiConfigManager.removeNetwork(eq(0), anyInt(), anyString())).thenReturn(true);
7297         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7298                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
7299 
7300         mLooper.startAutoDispatch();
7301         boolean result = mWifiServiceImpl.removeNetwork(0, TEST_PACKAGE_NAME);
7302         mLooper.stopAutoDispatchAndIgnoreExceptions();
7303 
7304         assertTrue(result);
7305         verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), anyString());
7306     }
7307 
7308     /**
7309      * Verify that addOrUpdatePasspointConfiguration is allowed for apps targeting below R SDK.
7310      */
7311     @Test
addOrUpdatePasspointConfigIsAllowedForAppsTargetingBelowRSdk()7312     public void addOrUpdatePasspointConfigIsAllowedForAppsTargetingBelowRSdk() throws Exception {
7313         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7314                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7315         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7316                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(true);
7317         PasspointConfiguration config = new PasspointConfiguration();
7318         HomeSp homeSp = new HomeSp();
7319         homeSp.setFqdn("test.com");
7320         config.setHomeSp(homeSp);
7321 
7322         when(mPasspointManager.addOrUpdateProvider(
7323                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7324                 .thenReturn(true);
7325         mLooper.startAutoDispatch();
7326         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7327         mLooper.stopAutoDispatchAndIgnoreExceptions();
7328         reset(mPasspointManager);
7329 
7330         when(mPasspointManager.addOrUpdateProvider(
7331                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7332                 .thenReturn(false);
7333         mLooper.startAutoDispatch();
7334         assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7335         mLooper.stopAutoDispatchAndIgnoreExceptions();
7336     }
7337 
7338     /**
7339      * Verify that addOrUpdatePasspointConfiguration is not allowed for apps targeting R SDK.
7340      */
7341     @Test
addOrUpdatePasspointConfigIsNotAllowedForAppsTargetingRSdk()7342     public void addOrUpdatePasspointConfigIsNotAllowedForAppsTargetingRSdk() throws Exception {
7343         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7344                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7345         PasspointConfiguration config = new PasspointConfiguration();
7346         HomeSp homeSp = new HomeSp();
7347         homeSp.setFqdn("test.com");
7348         config.setHomeSp(homeSp);
7349 
7350         when(mPasspointManager.addOrUpdateProvider(
7351                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7352                 .thenReturn(true);
7353         mLooper.startAutoDispatch();
7354         assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7355         mLooper.stopAutoDispatchAndIgnoreExceptions();
7356         verify(mPasspointManager, never())
7357                 .addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(), anyBoolean());
7358 
7359     }
7360 
7361     /**
7362      * Verify that addOrUpdatePasspointConfiguration is allowed for Settings apps.
7363      */
7364     @Test
addOrUpdatePasspointConfigIsAllowedSettingsApp()7365     public void addOrUpdatePasspointConfigIsAllowedSettingsApp() throws Exception {
7366         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
7367                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
7368         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7369                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7370         PasspointConfiguration config = new PasspointConfiguration();
7371         HomeSp homeSp = new HomeSp();
7372         homeSp.setFqdn("test.com");
7373         config.setHomeSp(homeSp);
7374 
7375         when(mPasspointManager.addOrUpdateProvider(
7376                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7377                 .thenReturn(true);
7378         mLooper.startAutoDispatch();
7379         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7380         mLooper.stopAutoDispatchAndIgnoreExceptions();
7381         verify(mPasspointManager).addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(),
7382                 anyBoolean());
7383     }
7384 
7385     /**
7386      * Verify that addOrUpdatePasspointConfiguration is allowed for System apps.
7387      */
7388     @Test
addOrUpdatePasspointConfigIsAllowedSystemApp()7389     public void addOrUpdatePasspointConfigIsAllowedSystemApp() throws Exception {
7390         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7391                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7392         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7393                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7394         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
7395         PasspointConfiguration config = new PasspointConfiguration();
7396         HomeSp homeSp = new HomeSp();
7397         homeSp.setFqdn("test.com");
7398         config.setHomeSp(homeSp);
7399 
7400         when(mPasspointManager.addOrUpdateProvider(
7401                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7402                 .thenReturn(true);
7403         mLooper.startAutoDispatch();
7404         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7405         mLooper.stopAutoDispatchAndIgnoreExceptions();
7406         verify(mPasspointManager).addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(),
7407                 anyBoolean());
7408     }
7409 
7410     /**
7411      * Verify that addOrUpdatePasspointConfiguration is allowed for DeviceOwner apps.
7412      */
7413     @Test
addOrUpdatePasspointConfigIsAllowedSystemAlertDOApp()7414     public void addOrUpdatePasspointConfigIsAllowedSystemAlertDOApp() throws Exception {
7415         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7416                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7417         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7418                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7419         when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
7420                 .thenReturn(true);
7421         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
7422                 .thenReturn(true);
7423         PasspointConfiguration config = new PasspointConfiguration();
7424         HomeSp homeSp = new HomeSp();
7425         homeSp.setFqdn("test.com");
7426         config.setHomeSp(homeSp);
7427 
7428         when(mPasspointManager.addOrUpdateProvider(
7429                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7430                 .thenReturn(true);
7431         mLooper.startAutoDispatch();
7432         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7433         mLooper.stopAutoDispatchAndIgnoreExceptions();
7434         verify(mPasspointManager).addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(),
7435                 anyBoolean());
7436     }
7437 
7438     /**
7439      * Verify that addOrUpdatePasspointConfiguration is allowed for ProfileOwner apps.
7440      */
7441     @Test
addOrUpdatePasspointConfigIsAllowedSystemAlertPOApp()7442     public void addOrUpdatePasspointConfigIsAllowedSystemAlertPOApp() throws Exception {
7443         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7444                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7445         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7446                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7447         when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
7448                 .thenReturn(true);
7449         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
7450                 .thenReturn(true);
7451         PasspointConfiguration config = new PasspointConfiguration();
7452         HomeSp homeSp = new HomeSp();
7453         homeSp.setFqdn("test.com");
7454         config.setHomeSp(homeSp);
7455 
7456         when(mPasspointManager.addOrUpdateProvider(
7457                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7458                 .thenReturn(true);
7459         mLooper.startAutoDispatch();
7460         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7461         mLooper.stopAutoDispatchAndIgnoreExceptions();
7462         verify(mPasspointManager).addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(),
7463                 anyBoolean());
7464     }
7465 
7466     /**
7467      * Verify that addOrUpdatePasspointConfiguration is not allowed for apps targeting below R SDK
7468      * when the DISALLOW_ADD_WIFI_CONFIG user restriction is set.
7469      */
7470     @Test
addOrUpdatePasspointConfigIsNotAllowedForAppsTargetingBelowRSdkWithUserRestriction()7471     public void addOrUpdatePasspointConfigIsNotAllowedForAppsTargetingBelowRSdkWithUserRestriction()
7472             throws Exception {
7473         assumeTrue(SdkLevel.isAtLeastT());
7474         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7475                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7476         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7477                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(true);
7478         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
7479                 any())).thenReturn(true);
7480         PasspointConfiguration config = new PasspointConfiguration();
7481         HomeSp homeSp = new HomeSp();
7482         homeSp.setFqdn("test.com");
7483         config.setHomeSp(homeSp);
7484 
7485         when(mPasspointManager.addOrUpdateProvider(
7486                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7487                 .thenReturn(true);
7488         mLooper.startAutoDispatch();
7489         assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7490         mLooper.stopAutoDispatchAndIgnoreExceptions();
7491         verify(mPasspointManager, never())
7492                 .addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(), anyBoolean());
7493     }
7494 
7495     /**
7496      * Verify that addOrUpdatePasspointConfiguration is not allowed for system apps
7497      * when the DISALLOW_ADD_WIFI_CONFIG user restriction is set.
7498      */
7499     @Test
addOrUpdatePasspointConfigIsNotAllowedForSystemAppWithUserRestriction()7500     public void addOrUpdatePasspointConfigIsNotAllowedForSystemAppWithUserRestriction()
7501             throws Exception {
7502         assumeTrue(SdkLevel.isAtLeastT());
7503         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7504                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7505         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7506                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7507         when(mWifiPermissionsUtil.isSystem(anyString(), anyInt())).thenReturn(true);
7508         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
7509                 any())).thenReturn(true);
7510         PasspointConfiguration config = new PasspointConfiguration();
7511         HomeSp homeSp = new HomeSp();
7512         homeSp.setFqdn("test.com");
7513         config.setHomeSp(homeSp);
7514 
7515         when(mPasspointManager.addOrUpdateProvider(
7516                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7517                 .thenReturn(true);
7518         mLooper.startAutoDispatch();
7519         assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7520         mLooper.stopAutoDispatchAndIgnoreExceptions();
7521         verify(mPasspointManager, never())
7522                 .addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(), anyBoolean());
7523     }
7524 
7525     /**
7526      * Verify that addOrUpdatePasspointConfiguration is allowed for admin apps
7527      * when the DISALLOW_ADD_WIFI_CONFIG user restriction is set.
7528      */
7529     @Test
addOrUpdatePasspointConfigIsAllowedSystemAlertAdminAppWithUserRestriction()7530     public void addOrUpdatePasspointConfigIsAllowedSystemAlertAdminAppWithUserRestriction()
7531             throws Exception {
7532         assumeTrue(SdkLevel.isAtLeastT());
7533         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7534                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7535         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7536                 eq(Build.VERSION_CODES.R), anyInt())).thenReturn(false);
7537         when(mWifiPermissionsUtil.isAdmin(Binder.getCallingUid(), TEST_PACKAGE_NAME))
7538                 .thenReturn(true);
7539         when(mUserManager.hasUserRestrictionForUser(eq(UserManager.DISALLOW_ADD_WIFI_CONFIG),
7540                 any())).thenReturn(true);
7541         PasspointConfiguration config = new PasspointConfiguration();
7542         HomeSp homeSp = new HomeSp();
7543         homeSp.setFqdn("test.com");
7544         config.setHomeSp(homeSp);
7545 
7546         when(mPasspointManager.addOrUpdateProvider(
7547                 config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false, true))
7548                 .thenReturn(true);
7549         mLooper.startAutoDispatch();
7550         assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
7551         mLooper.stopAutoDispatchAndIgnoreExceptions();
7552         verify(mPasspointManager).addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean(),
7553                 anyBoolean());
7554     }
7555 
7556     /**
7557      * Verify that removePasspointConfiguration will redirect calls to {@link PasspointManager}
7558      * and returning the result that's returned from {@link PasspointManager}.
7559      */
7560     @Test
removePasspointConfig()7561     public void removePasspointConfig() throws Exception {
7562         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
7563 
7564         String fqdn = "test.com";
7565         when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), isNull(), eq(fqdn)))
7566                 .thenReturn(true);
7567         mLooper.startAutoDispatch();
7568         assertTrue(mWifiServiceImpl.removePasspointConfiguration(fqdn, TEST_PACKAGE_NAME));
7569         mLooper.stopAutoDispatchAndIgnoreExceptions();
7570         reset(mPasspointManager);
7571 
7572         when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), isNull(), eq(fqdn)))
7573                 .thenReturn(false);
7574         mLooper.startAutoDispatch();
7575         assertFalse(mWifiServiceImpl.removePasspointConfiguration(fqdn, TEST_PACKAGE_NAME));
7576         mLooper.stopAutoDispatchAndIgnoreExceptions();
7577     }
7578 
7579     /**
7580      * Test that DISABLE_NETWORK returns failure to public API when WifiConfigManager returns
7581      * failure.
7582      */
7583     @Test
testDisableNetworkFailureAppBelowQSdk()7584     public void testDisableNetworkFailureAppBelowQSdk() throws Exception {
7585         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
7586                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
7587         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
7588                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
7589         when(mWifiConfigManager.disableNetwork(anyInt(), anyInt(), anyString())).thenReturn(false);
7590 
7591         mLooper.startAutoDispatch();
7592         boolean succeeded = mWifiServiceImpl.disableNetwork(0, TEST_PACKAGE_NAME);
7593         mLooper.stopAutoDispatchAndIgnoreExceptions();
7594         assertFalse(succeeded);
7595     }
7596 
7597     @Test(expected = SecurityException.class)
testAllowAutojoinGlobalFailureNoPermission()7598     public void testAllowAutojoinGlobalFailureNoPermission() throws Exception {
7599         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
7600         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7601                 .thenReturn(false);
7602         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(false);
7603         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(false);
7604         mWifiServiceImpl.allowAutojoinGlobal(true);
7605     }
7606 
7607     @Test
testAllowAutojoinGlobalWithPermission()7608     public void testAllowAutojoinGlobalWithPermission() throws Exception {
7609         // verify allowAutojoinGlobal with MANAGE_WIFI_NETWORK_SELECTION
7610         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
7611         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7612                 .thenReturn(true);
7613         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(false);
7614         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(false);
7615         mWifiServiceImpl.allowAutojoinGlobal(true);
7616 
7617         // verify allowAutojoinGlobal with NETWORK_SETTINGS
7618         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
7619         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7620                 .thenReturn(false);
7621         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(false);
7622         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(false);
7623         mWifiServiceImpl.allowAutojoinGlobal(true);
7624 
7625         // verify allowAutojoinGlobal with DO
7626         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
7627         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7628                 .thenReturn(false);
7629         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(true);
7630         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(false);
7631         mWifiServiceImpl.allowAutojoinGlobal(true);
7632 
7633         // verify allowAutojoinGlobal with PO
7634         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
7635         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7636                 .thenReturn(false);
7637         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(false);
7638         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(true);
7639         mWifiServiceImpl.allowAutojoinGlobal(true);
7640     }
7641 
7642     @Test
testQueryAutojoinGlobal_Exceptions()7643     public void testQueryAutojoinGlobal_Exceptions() {
7644         // good inputs should result in no exceptions.
7645         IBooleanListener listener = mock(IBooleanListener.class);
7646         // null listener ==> IllegalArgumentException
7647         assertThrows(IllegalArgumentException.class,
7648                 () -> mWifiServiceImpl.queryAutojoinGlobal(null));
7649 
7650         // No permission ==> SecurityException
7651         assertThrows(SecurityException.class,
7652                 () -> mWifiServiceImpl.queryAutojoinGlobal(listener));
7653     }
7654 
7655     @Test
testQueryAutojoinGlobal_GoodCase()7656     public void testQueryAutojoinGlobal_GoodCase() throws RemoteException {
7657         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
7658         IBooleanListener listener = mock(IBooleanListener.class);
7659 
7660         InOrder inOrder = inOrder(listener);
7661         when(mWifiConnectivityManager.getAutoJoinEnabledExternal()).thenReturn(true);
7662         mWifiServiceImpl.queryAutojoinGlobal(listener);
7663         mLooper.dispatchAll();
7664         inOrder.verify(listener).onResult(true);
7665 
7666         when(mWifiConnectivityManager.getAutoJoinEnabledExternal()).thenReturn(false);
7667         mWifiServiceImpl.queryAutojoinGlobal(listener);
7668         mLooper.dispatchAll();
7669         inOrder.verify(listener).onResult(false);
7670     }
7671 
7672     @Test(expected = SecurityException.class)
testSetSsidsDoNotBlocklist_NoPermission()7673     public void testSetSsidsDoNotBlocklist_NoPermission() throws Exception {
7674         // by default no permissions are given so the call should fail.
7675         mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
7676                 Collections.EMPTY_LIST);
7677     }
7678 
7679     @Test
testSetSsidsDoNotBlocklist_WithPermission()7680     public void testSetSsidsDoNotBlocklist_WithPermission() throws Exception {
7681         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
7682 
7683         // verify setting an empty list
7684         mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
7685                 Collections.EMPTY_LIST);
7686         mLooper.dispatchAll();
7687         verify(mWifiBlocklistMonitor).setSsidsAllowlist(Collections.EMPTY_LIST);
7688 
7689         // verify setting a list of valid SSIDs
7690         List<WifiSsid> expectedSsids = new ArrayList<>();
7691         expectedSsids.add(WifiSsid.fromString(TEST_SSID_WITH_QUOTES));
7692         mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME, expectedSsids);
7693         mLooper.dispatchAll();
7694         verify(mWifiBlocklistMonitor).setSsidsAllowlist(expectedSsids);
7695     }
7696 
7697     @Test
testSetSsidsDoNotBlocklist_WithPermissionAndroidT()7698     public void testSetSsidsDoNotBlocklist_WithPermissionAndroidT()
7699             throws Exception {
7700         assumeTrue(SdkLevel.isAtLeastT());
7701         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
7702                 .thenReturn(true);
7703 
7704         List<WifiSsid> expectedSsids = new ArrayList<>();
7705         expectedSsids.add(WifiSsid.fromString(TEST_SSID_WITH_QUOTES));
7706         mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME, expectedSsids);
7707         mLooper.dispatchAll();
7708         verify(mWifiBlocklistMonitor).setSsidsAllowlist(expectedSsids);
7709     }
7710 
7711     @Test
testAllowAutojoinFailureNoNetworkSettingsPermission()7712     public void testAllowAutojoinFailureNoNetworkSettingsPermission() throws Exception {
7713         doThrow(new SecurityException()).when(mContext)
7714                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
7715                         eq("WifiService"));
7716         try {
7717             mWifiServiceImpl.allowAutojoin(0, true);
7718             fail("Expected SecurityException");
7719         } catch (SecurityException e) {
7720             // Test succeeded
7721         }
7722     }
7723 
7724     @Test
testAllowAutojoinOnSuggestionNetwork()7725     public void testAllowAutojoinOnSuggestionNetwork() {
7726         WifiConfiguration config = new WifiConfiguration();
7727         config.allowAutojoin = false;
7728         config.fromWifiNetworkSuggestion = true;
7729         when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config);
7730         when(mWifiNetworkSuggestionsManager.allowNetworkSuggestionAutojoin(any(), anyBoolean()))
7731                 .thenReturn(true);
7732         mWifiServiceImpl.allowAutojoin(0, true);
7733         mLooper.dispatchAll();
7734         verify(mWifiConfigManager).getConfiguredNetwork(0);
7735         verify(mWifiNetworkSuggestionsManager).allowNetworkSuggestionAutojoin(any(), anyBoolean());
7736         verify(mWifiConfigManager).allowAutojoin(anyInt(), anyBoolean());
7737         verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON),
7738                 anyInt());
7739     }
7740 
7741     @Test
testAllowAutojoinOnSavedNetwork()7742     public void testAllowAutojoinOnSavedNetwork() {
7743         WifiConfiguration config = new WifiConfiguration();
7744         config.allowAutojoin = false;
7745         config.fromWifiNetworkSuggestion = false;
7746         config.fromWifiNetworkSpecifier = false;
7747         when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config);
7748         mWifiServiceImpl.allowAutojoin(0, true);
7749         mLooper.dispatchAll();
7750         verify(mWifiConfigManager).getConfiguredNetwork(0);
7751         verify(mWifiNetworkSuggestionsManager, never())
7752                 .allowNetworkSuggestionAutojoin(any(), anyBoolean());
7753         verify(mWifiConfigManager).allowAutojoin(anyInt(), anyBoolean());
7754     }
7755 
7756     @Test
testAllowAutojoinOnWifiNetworkSpecifier()7757     public void testAllowAutojoinOnWifiNetworkSpecifier() {
7758         WifiConfiguration config = new WifiConfiguration();
7759         config.fromWifiNetworkSpecifier = true;
7760         when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config);
7761         mWifiServiceImpl.allowAutojoin(0, true);
7762         mLooper.dispatchAll();
7763         verify(mWifiConfigManager).getConfiguredNetwork(0);
7764         verify(mWifiNetworkSuggestionsManager, never())
7765                 .allowNetworkSuggestionAutojoin(config, true);
7766         verify(mWifiConfigManager, never()).allowAutojoin(0, true);
7767     }
7768 
7769     @Test
testAllowAutojoinOnSavedPasspointNetwork()7770     public void testAllowAutojoinOnSavedPasspointNetwork() {
7771         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
7772         when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config);
7773         when(mWifiNetworkSuggestionsManager.allowNetworkSuggestionAutojoin(any(), anyBoolean()))
7774                 .thenReturn(true);
7775         mWifiServiceImpl.allowAutojoin(0, true);
7776         mLooper.dispatchAll();
7777         verify(mWifiConfigManager).getConfiguredNetwork(0);
7778         verify(mWifiNetworkSuggestionsManager, never())
7779                 .allowNetworkSuggestionAutojoin(config, true);
7780         verify(mWifiConfigManager, never()).allowAutojoin(0, true);
7781     }
7782 
7783     /**
7784      * Test that setMacRandomizationSettingPasspointEnabled is protected by NETWORK_SETTINGS
7785      * permission.
7786      */
7787     @Test
testSetMacRandomizationSettingPasspointEnabledFailureNoNetworkSettingsPermission()7788     public void testSetMacRandomizationSettingPasspointEnabledFailureNoNetworkSettingsPermission()
7789             throws Exception {
7790         doThrow(new SecurityException()).when(mContext)
7791                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
7792                         eq("WifiService"));
7793         try {
7794             mWifiServiceImpl.setMacRandomizationSettingPasspointEnabled("TEST_FQDN", true);
7795             fail("Expected SecurityException");
7796         } catch (SecurityException e) {
7797             // Test succeeded
7798         }
7799     }
7800 
7801     /**
7802      * Test that setMacRandomizationSettingPasspointEnabled makes the appropriate calls.
7803      */
7804     @Test
testSetMacRandomizationSettingPasspointEnabled()7805     public void testSetMacRandomizationSettingPasspointEnabled() throws Exception {
7806         mWifiServiceImpl.setMacRandomizationSettingPasspointEnabled("TEST_FQDN", true);
7807         mLooper.dispatchAll();
7808         verify(mPasspointManager).enableMacRandomization("TEST_FQDN", true);
7809     }
7810 
7811     /**
7812      * Test that setPasspointMeteredOverride is protected by NETWORK_SETTINGS permission.
7813      */
7814     @Test
testSetPasspointMeteredOverrideFailureNoNetworkSettingsPermission()7815     public void testSetPasspointMeteredOverrideFailureNoNetworkSettingsPermission()
7816             throws Exception {
7817         doThrow(new SecurityException()).when(mContext)
7818                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
7819                         eq("WifiService"));
7820         try {
7821             mWifiServiceImpl.setPasspointMeteredOverride("TEST_FQDN", METERED_OVERRIDE_METERED);
7822             fail("Expected SecurityException");
7823         } catch (SecurityException e) {
7824             // Test succeeded
7825         }
7826     }
7827 
7828     /**
7829      * Test that setPasspointMeteredOverride makes the appropriate calls.
7830      */
7831     @Test
testSetPasspointMeteredOverride()7832     public void testSetPasspointMeteredOverride() throws Exception {
7833         mWifiServiceImpl.setPasspointMeteredOverride("TEST_FQDN", METERED_OVERRIDE_METERED);
7834         mLooper.dispatchAll();
7835         verify(mPasspointManager).setMeteredOverride("TEST_FQDN", METERED_OVERRIDE_METERED);
7836     }
7837 
7838     /**
7839      * Test handle boot completed sequence.
7840      */
7841     @Test
testHandleBootCompleted()7842     public void testHandleBootCompleted() throws Exception {
7843         when(mWifiInjector.getPasspointProvisionerHandlerThread())
7844                 .thenReturn(mock(HandlerThread.class));
7845         mLooper.startAutoDispatch();
7846         mWifiServiceImpl.handleBootCompleted();
7847         mLooper.stopAutoDispatch();
7848 
7849         verify(mWifiNetworkFactory).register();
7850         verify(mUntrustedWifiNetworkFactory).register();
7851         verify(mOemWifiNetworkFactory).register();
7852         verify(mRestrictedWifiNetworkFactory).register();
7853         verify(mMultiInternetWifiNetworkFactory).register();
7854         verify(mPasspointManager).initializeProvisioner(any());
7855         verify(mWifiP2pConnection).handleBootCompleted();
7856         verify(mWifiCountryCode).registerListener(any(WifiCountryCode.ChangeListener.class));
7857     }
7858 
7859     /**
7860      * Test handle user switch sequence.
7861      */
7862     @Test
testHandleUserSwitch()7863     public void testHandleUserSwitch() throws Exception {
7864         mWifiServiceImpl.handleUserSwitch(5);
7865         mLooper.dispatchAll();
7866         verify(mWifiConfigManager).handleUserSwitch(5);
7867         verify(mWifiNotificationManager).createNotificationChannels();
7868         verify(mWifiNetworkSuggestionsManager).resetNotification();
7869         verify(mWifiCarrierInfoManager).resetNotification();
7870         verify(mOpenNetworkNotifier).clearPendingNotification(false);
7871         verify(mWakeupController).resetNotification();
7872     }
7873 
7874     /**
7875      * Test handle user unlock sequence.
7876      */
7877     @Test
testHandleUserUnlock()7878     public void testHandleUserUnlock() throws Exception {
7879         mWifiServiceImpl.handleUserUnlock(5);
7880         mLooper.dispatchAll();
7881         verify(mWifiConfigManager).handleUserUnlock(5);
7882     }
7883 
7884     /**
7885      * Test handle user stop sequence.
7886      */
7887     @Test
testHandleUserStop()7888     public void testHandleUserStop() throws Exception {
7889         mWifiServiceImpl.handleUserStop(5);
7890         mLooper.dispatchAll();
7891         verify(mWifiConfigManager).handleUserStop(5);
7892     }
7893 
7894     /**
7895      * Test register scan result callback without permission.
7896      */
7897     @Test(expected = SecurityException.class)
testRegisterScanResultCallbackWithMissingPermission()7898     public void testRegisterScanResultCallbackWithMissingPermission() throws Exception {
7899         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
7900                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
7901         mWifiServiceImpl.registerScanResultsCallback(mScanResultsCallback);
7902     }
7903 
7904     /**
7905      * Test unregister scan result callback without permission.
7906      */
7907     @Test(expected = SecurityException.class)
testUnregisterScanResultCallbackWithMissingPermission()7908     public void testUnregisterScanResultCallbackWithMissingPermission() throws Exception {
7909         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
7910                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
7911         mWifiServiceImpl.unregisterScanResultsCallback(mScanResultsCallback);
7912     }
7913 
7914     /**
7915      * Test register scan result callback with illegal argument.
7916      */
7917     @Test(expected = IllegalArgumentException.class)
testRegisterScanResultCallbackWithIllegalArgument()7918     public void testRegisterScanResultCallbackWithIllegalArgument() throws Exception {
7919         mWifiServiceImpl.registerScanResultsCallback(null);
7920     }
7921 
7922     /**
7923      * Test register and unregister callback will go to ScanRequestProxy;
7924      */
7925     @Test
testRegisterUnregisterScanResultCallback()7926     public void testRegisterUnregisterScanResultCallback() throws Exception {
7927         mWifiServiceImpl.registerScanResultsCallback(mScanResultsCallback);
7928         mLooper.dispatchAll();
7929         verify(mScanRequestProxy).registerScanResultsCallback(mScanResultsCallback);
7930         mWifiServiceImpl.unregisterScanResultsCallback(mScanResultsCallback);
7931         mLooper.dispatchAll();
7932         verify(mScanRequestProxy).unregisterScanResultsCallback(mScanResultsCallback);
7933     }
7934 
7935     /**
7936      * Test register callback without permission.
7937      */
7938     @Test(expected = SecurityException.class)
testRegisterSuggestionNetworkCallbackWithMissingPermission()7939     public void testRegisterSuggestionNetworkCallbackWithMissingPermission() {
7940         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
7941                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
7942         mWifiServiceImpl.registerSuggestionConnectionStatusListener(
7943                 mSuggestionConnectionStatusListener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
7944     }
7945 
7946     /**
7947      * Test register callback without callback
7948      */
7949     @Test(expected = IllegalArgumentException.class)
testRegisterSuggestionNetworkCallbackWithIllegalArgument()7950     public void testRegisterSuggestionNetworkCallbackWithIllegalArgument() {
7951         mWifiServiceImpl.registerSuggestionConnectionStatusListener(null, TEST_PACKAGE_NAME,
7952                 TEST_FEATURE_ID);
7953     }
7954 
7955     /**
7956      * Test unregister callback without permission.
7957      */
7958     @Test(expected = SecurityException.class)
testUnregisterSuggestionNetworkCallbackWithMissingPermission()7959     public void testUnregisterSuggestionNetworkCallbackWithMissingPermission() {
7960         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
7961                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
7962         mWifiServiceImpl.unregisterSuggestionConnectionStatusListener(
7963                 mSuggestionConnectionStatusListener, TEST_PACKAGE_NAME);
7964     }
7965 
7966     /**
7967      * Test register nad unregister callback will go to WifiNetworkSuggestionManager
7968      */
7969     @Test
testRegisterUnregisterSuggestionNetworkCallback()7970     public void testRegisterUnregisterSuggestionNetworkCallback() throws Exception {
7971         mWifiServiceImpl.registerSuggestionConnectionStatusListener(
7972                 mSuggestionConnectionStatusListener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
7973         mLooper.dispatchAll();
7974         verify(mWifiNetworkSuggestionsManager).registerSuggestionConnectionStatusListener(
7975                 eq(mSuggestionConnectionStatusListener), eq(TEST_PACKAGE_NAME), anyInt());
7976         mWifiServiceImpl.unregisterSuggestionConnectionStatusListener(
7977                 mSuggestionConnectionStatusListener, TEST_PACKAGE_NAME);
7978         mLooper.dispatchAll();
7979         verify(mWifiNetworkSuggestionsManager).unregisterSuggestionConnectionStatusListener(
7980                 eq(mSuggestionConnectionStatusListener), eq(TEST_PACKAGE_NAME), anyInt());
7981     }
7982 
7983 
7984     /**
7985      * Test to verify that the lock mode is verified before dispatching the operation
7986      *
7987      * Steps: call acquireWifiLock with an invalid lock mode.
7988      * Expected: the call should throw an IllegalArgumentException.
7989      */
7990     @Test(expected = IllegalArgumentException.class)
acquireWifiLockShouldThrowExceptionOnInvalidLockMode()7991     public void acquireWifiLockShouldThrowExceptionOnInvalidLockMode() throws Exception {
7992         final int wifiLockModeInvalid = -1;
7993 
7994         mWifiServiceImpl.acquireWifiLock(mAppBinder, wifiLockModeInvalid, "", null);
7995     }
7996 
setupReportActivityInfo()7997     private void setupReportActivityInfo() {
7998         WifiLinkLayerStats stats = new WifiLinkLayerStats();
7999         stats.on_time = 1000;
8000         stats.tx_time = 1;
8001         stats.rx_time = 2;
8002         stats.tx_time_per_level = new int[] {3, 4, 5};
8003         stats.on_time_scan = 6;
8004         when(mClientModeManager.getWifiLinkLayerStats()).thenReturn(stats);
8005         when(mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE))
8006                 .thenReturn(7.0);
8007         when(mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX))
8008                 .thenReturn(8.0);
8009         when(mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_TX))
8010                 .thenReturn(9.0);
8011         when(mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE))
8012                 .thenReturn(10000.0);
8013         when(mClock.getElapsedSinceBootMillis()).thenReturn(9999L);
8014     }
8015 
validateWifiActivityEnergyInfo(WifiActivityEnergyInfo info)8016     private void validateWifiActivityEnergyInfo(WifiActivityEnergyInfo info) {
8017         assertNotNull(info);
8018         assertEquals(9999L, info.getTimeSinceBootMillis());
8019         assertEquals(WifiActivityEnergyInfo.STACK_STATE_STATE_IDLE, info.getStackState());
8020         assertEquals(1, info.getControllerTxDurationMillis());
8021         assertEquals(2, info.getControllerRxDurationMillis());
8022         assertEquals(6, info.getControllerScanDurationMillis());
8023         assertEquals(997, info.getControllerIdleDurationMillis());
8024     }
8025 
8026     /**
8027      * Tests that {@link WifiServiceImpl#getWifiActivityEnergyInfoAsync} throws
8028      * {@link SecurityException} if the caller doesn't have the necessary permissions.
8029      */
8030     @Test(expected = SecurityException.class)
getWifiActivityEnergyInfoAsyncNoPermission()8031     public void getWifiActivityEnergyInfoAsyncNoPermission() throws Exception {
8032         doThrow(SecurityException.class)
8033                 .when(mContext).enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE), any());
8034         mWifiServiceImpl.getWifiActivityEnergyInfoAsync(mOnWifiActivityEnergyInfoListener);
8035     }
8036 
8037     /**
8038      * Tests that {@link WifiServiceImpl#getWifiActivityEnergyInfoAsync} passes null to the listener
8039      * if link layer stats is unsupported.
8040      */
8041     @Test
getWifiActivityEnergyInfoAsyncFeatureUnsupported()8042     public void getWifiActivityEnergyInfoAsyncFeatureUnsupported() throws Exception {
8043         when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn(0L);
8044         mLooper.startAutoDispatch();
8045         mWifiServiceImpl.getWifiActivityEnergyInfoAsync(mOnWifiActivityEnergyInfoListener);
8046         mLooper.stopAutoDispatch();
8047         verify(mOnWifiActivityEnergyInfoListener).onWifiActivityEnergyInfo(null);
8048     }
8049 
8050     /**
8051      * Tests that {@link WifiServiceImpl#getWifiActivityEnergyInfoAsync} passes the expected values
8052      * to the listener on success.
8053      */
8054     @Test
getWifiActivityEnergyInfoAsyncSuccess()8055     public void getWifiActivityEnergyInfoAsyncSuccess() throws Exception {
8056         when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn(Long.MAX_VALUE);
8057         setupReportActivityInfo();
8058         mLooper.startAutoDispatch();
8059         mWifiServiceImpl.getWifiActivityEnergyInfoAsync(mOnWifiActivityEnergyInfoListener);
8060         mLooper.stopAutoDispatch();
8061         ArgumentCaptor<WifiActivityEnergyInfo> infoCaptor =
8062                 ArgumentCaptor.forClass(WifiActivityEnergyInfo.class);
8063         verify(mOnWifiActivityEnergyInfoListener).onWifiActivityEnergyInfo(infoCaptor.capture());
8064         validateWifiActivityEnergyInfo(infoCaptor.getValue());
8065     }
8066 
8067     @Test
testCarrierConfigChangeUpdateSoftApCapability()8068     public void testCarrierConfigChangeUpdateSoftApCapability() throws Exception {
8069         lenient().when(SubscriptionManager.getActiveDataSubscriptionId())
8070                 .thenReturn(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
8071         mWifiServiceImpl.checkAndStartWifi();
8072         mLooper.dispatchAll();
8073         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
8074                 argThat((IntentFilter filter) ->
8075                         filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)),
8076                 isNull(),
8077                 any(Handler.class));
8078 
8079         // Send the broadcast
8080         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
8081         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
8082         mLooper.dispatchAll();
8083         verify(mActiveModeWarden).updateSoftApCapability(any(),
8084                 eq(WifiManager.IFACE_IP_MODE_TETHERED));
8085     }
8086 
8087     @Test
testPhoneActiveDataSubscriptionIdChangedUpdateSoftApCapability()8088     public void testPhoneActiveDataSubscriptionIdChangedUpdateSoftApCapability() throws Exception {
8089         lenient().when(SubscriptionManager.getActiveDataSubscriptionId())
8090                 .thenReturn(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
8091         mWifiServiceImpl.checkAndStartWifi();
8092         mLooper.dispatchAll();
8093         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
8094                 argThat((IntentFilter filter) ->
8095                         filter.hasAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)),
8096                 isNull(),
8097                 any(Handler.class));
8098         ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
8099                 ArgumentCaptor.forClass(PhoneStateListener.class);
8100         verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(),
8101                 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
8102         mPhoneStateListener = phoneStateListenerCaptor.getValue();
8103         assertNotNull(mPhoneStateListener);
8104         mPhoneStateListener.onActiveDataSubscriptionIdChanged(2);
8105         mLooper.dispatchAll();
8106         verify(mActiveModeWarden).updateSoftApCapability(any(),
8107                 eq(WifiManager.IFACE_IP_MODE_TETHERED));
8108     }
8109 
8110     /**
8111      * Verify that the call to getWifiConfigsForMatchedNetworkSuggestions is not redirected to
8112      * specific API getWifiConfigForMatchedNetworkSuggestionsSharedWithUser when the caller doesn't
8113      * have NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
8114      */
8115     @Test(expected = SecurityException.class)
testGetWifiConfigsForMatchedNetworkSuggestionsWithoutPermissions()8116     public void testGetWifiConfigsForMatchedNetworkSuggestionsWithoutPermissions() {
8117         mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
8118     }
8119 
8120     /**
8121      * Verify that the call to getWifiConfigsForMatchedNetworkSuggestions is redirected to
8122      * specific API getWifiConfigForMatchedNetworkSuggestionsSharedWithUser when the caller
8123      * have NETWORK_SETTINGS.
8124      */
8125     @Test
testGetWifiConfigsForMatchedNetworkSuggestionsWithSettingPermissions()8126     public void testGetWifiConfigsForMatchedNetworkSuggestionsWithSettingPermissions() {
8127         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8128                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
8129         mLooper.startAutoDispatch();
8130         mWifiServiceImpl
8131                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
8132         mLooper.stopAutoDispatch();
8133         verify(mWifiNetworkSuggestionsManager)
8134                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
8135     }
8136 
8137     /**
8138      * Verify that the call to getWifiConfigsForMatchedNetworkSuggestions is redirected to
8139      * specific API getWifiConfigForMatchedNetworkSuggestionsSharedWithUser when the caller
8140      * have NETWORK_SETUP_WIZARD.
8141      */
8142     @Test
testGetWifiConfigsForMatchedNetworkSuggestionsWithSetupWizardPermissions()8143     public void testGetWifiConfigsForMatchedNetworkSuggestionsWithSetupWizardPermissions() {
8144         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
8145                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
8146         mLooper.startAutoDispatch();
8147         mWifiServiceImpl
8148                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
8149         mLooper.stopAutoDispatch();
8150         verify(mWifiNetworkSuggestionsManager)
8151                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
8152     }
8153 
8154     @Test
testGetWifiConfigsForMatchedNetworkSuggestionsWithInvalidScanResults()8155     public void testGetWifiConfigsForMatchedNetworkSuggestionsWithInvalidScanResults() {
8156         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8157                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
8158         mWifiServiceImpl
8159                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
8160         mLooper.dispatchAll();
8161         verify(mWifiNetworkSuggestionsManager, never())
8162                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
8163     }
8164 
8165     /**
8166      * Verify that a call to setWifiConnectedNetworkScorer throws a SecurityException if
8167      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
8168      */
8169     @Test
testSetNetworkScorerThrowsSecurityExceptionOnMissingPermissions()8170     public void testSetNetworkScorerThrowsSecurityExceptionOnMissingPermissions() {
8171         doThrow(new SecurityException()).when(mContext)
8172                 .enforceCallingOrSelfPermission(
8173                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
8174                         eq("WifiService"));
8175         try {
8176             mWifiServiceImpl.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
8177             fail("expected SecurityException");
8178         } catch (SecurityException expected) {
8179         }
8180     }
8181 
8182     /**
8183      * Verify that a call to setWifiConnectedNetworkScorer throws an IllegalArgumentException
8184      * if the parameters are not provided.
8185      */
8186     @Test
testSetScorerThrowsIllegalArgumentExceptionOnInvalidArguments()8187     public void testSetScorerThrowsIllegalArgumentExceptionOnInvalidArguments() {
8188         try {
8189             mWifiServiceImpl.setWifiConnectedNetworkScorer(mAppBinder, null);
8190             fail("expected IllegalArgumentException");
8191         } catch (IllegalArgumentException expected) {
8192         }
8193     }
8194 
8195     /**
8196      * Verify that a call to clearWifiConnectedNetworkScorer throws a SecurityException if
8197      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
8198      */
8199     @Test
testClearNetworkScorerThrowsSecurityExceptionOnMissingPermissions()8200     public void testClearNetworkScorerThrowsSecurityExceptionOnMissingPermissions() {
8201         doThrow(new SecurityException()).when(mContext)
8202                 .enforceCallingOrSelfPermission(
8203                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
8204                                 eq("WifiService"));
8205         try {
8206             mWifiServiceImpl.clearWifiConnectedNetworkScorer();
8207             fail("expected SecurityException");
8208         } catch (SecurityException expected) {
8209         }
8210     }
8211 
8212     /**
8213      * Verify that setWifiConnectedNetworkScorer sets scorer to {@link WifiScoreReport}.
8214      */
8215     @Test
testSetWifiConnectedNetworkScorerAndVerify()8216     public void testSetWifiConnectedNetworkScorerAndVerify() throws Exception {
8217         mLooper.startAutoDispatch();
8218         mWifiServiceImpl.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
8219         mLooper.stopAutoDispatch();
8220         verify(mActiveModeWarden).setWifiConnectedNetworkScorer(
8221                 mAppBinder, mWifiConnectedNetworkScorer);
8222     }
8223 
8224     /**
8225      * Verify that clearWifiConnectedNetworkScorer clears scorer from {@link WifiScoreReport}.
8226      */
8227     @Test
testClearWifiConnectedNetworkScorerAndVerify()8228     public void testClearWifiConnectedNetworkScorerAndVerify() throws Exception {
8229         mWifiServiceImpl.clearWifiConnectedNetworkScorer();
8230         mLooper.dispatchAll();
8231         verify(mActiveModeWarden).clearWifiConnectedNetworkScorer();
8232     }
8233 
8234     /**
8235      * Verify that a call to addWifiCustomDhcpOptions throws a SecurityException if
8236      * the caller does not have NETWORK_SETTINGS or OVERRIDE_WIFI_CONFIG permission.
8237      */
8238     @Test
testAddCustomDhcpOptionsThrowsSecurityExceptionOnMissingPermissions()8239     public void testAddCustomDhcpOptionsThrowsSecurityExceptionOnMissingPermissions() {
8240         assumeTrue(SdkLevel.isAtLeastT());
8241         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS))
8242                 .thenReturn(PackageManager.PERMISSION_DENIED);
8243         when(mContext.checkCallingOrSelfPermission(
8244                 android.Manifest.permission.OVERRIDE_WIFI_CONFIG))
8245                 .thenReturn(PackageManager.PERMISSION_DENIED);
8246         try {
8247             mWifiServiceImpl.addCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
8248                     TEST_OUI, new ArrayList<DhcpOption>());
8249             fail("expected SecurityException");
8250         } catch (SecurityException expected) {
8251         }
8252     }
8253 
8254     /**
8255      * Verify that a call to removeWifiCustomDhcpOptions throws a SecurityException if
8256      * the caller does not have NETWORK_SETTINGS or OVERRIDE_WIFI_CONFIG permission.
8257      */
8258     @Test
testRemoveCustomDhcpOptionsThrowsSecurityExceptionOnMissingPermissions()8259     public void testRemoveCustomDhcpOptionsThrowsSecurityExceptionOnMissingPermissions() {
8260         assumeTrue(SdkLevel.isAtLeastT());
8261         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS))
8262                 .thenReturn(PackageManager.PERMISSION_DENIED);
8263         when(mContext.checkCallingOrSelfPermission(
8264                 android.Manifest.permission.OVERRIDE_WIFI_CONFIG))
8265                 .thenReturn(PackageManager.PERMISSION_DENIED);
8266         try {
8267             mWifiServiceImpl.removeCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
8268                     TEST_OUI);
8269             fail("expected SecurityException");
8270         } catch (SecurityException expected) {
8271         }
8272     }
8273 
8274     /**
8275      * Verify that addWifiCustomDhcpOptions adds DHCP option.
8276      */
8277     @Test
testAddCustomDhcpOptionsAndVerify()8278     public void testAddCustomDhcpOptionsAndVerify() throws Exception {
8279         assumeTrue(SdkLevel.isAtLeastT());
8280         mWifiServiceImpl.addCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_OUI,
8281                 new ArrayList<DhcpOption>());
8282         mLooper.dispatchAll();
8283         verify(mWifiConfigManager).addCustomDhcpOptions(
8284                 WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_OUI, new ArrayList<DhcpOption>());
8285     }
8286 
8287     /**
8288      * Verify that removeWifiCustomDhcpOptions removes DHCP option.
8289      */
8290     @Test
testRemoveCustomDhcpOptionsAndVerify()8291     public void testRemoveCustomDhcpOptionsAndVerify() throws Exception {
8292         assumeTrue(SdkLevel.isAtLeastT());
8293         mWifiServiceImpl.removeCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
8294                 TEST_OUI);
8295         mLooper.dispatchAll();
8296         verify(mWifiConfigManager).removeCustomDhcpOptions(
8297                 WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_OUI);
8298     }
8299 
testGetSupportedFeaturesCaseForRtt( long supportedFeaturesFromWifiNative, boolean rttDisabled)8300     private long testGetSupportedFeaturesCaseForRtt(
8301             long supportedFeaturesFromWifiNative, boolean rttDisabled) {
8302         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(
8303                 !rttDisabled);
8304         when(mWifiNative.getSupportedFeatureSet(anyString()))
8305                 .thenReturn(supportedFeaturesFromWifiNative);
8306         mLooper.startAutoDispatch();
8307         long supportedFeatures = mWifiServiceImpl.getSupportedFeatures();
8308         mLooper.stopAutoDispatchAndIgnoreExceptions();
8309         return supportedFeatures;
8310     }
8311 
8312     /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */
8313     @Test
syncGetSupportedFeaturesForRtt()8314     public void syncGetSupportedFeaturesForRtt() {
8315         final long featureAware = WifiManager.WIFI_FEATURE_AWARE;
8316         final long featureInfra = WifiManager.WIFI_FEATURE_INFRA;
8317         final long featureD2dRtt = WifiManager.WIFI_FEATURE_D2D_RTT;
8318         final long featureD2apRtt = WifiManager.WIFI_FEATURE_D2AP_RTT;
8319         final long featureLongBits = 0x1000000000L;
8320 
8321         assertEquals(0, testGetSupportedFeaturesCaseForRtt(0, false));
8322         assertEquals(0, testGetSupportedFeaturesCaseForRtt(0, true));
8323         assertEquals(featureAware | featureInfra,
8324                 testGetSupportedFeaturesCaseForRtt(featureAware | featureInfra, false));
8325         assertEquals(featureAware | featureInfra,
8326                 testGetSupportedFeaturesCaseForRtt(featureAware | featureInfra, true));
8327         assertEquals(featureInfra | featureD2dRtt,
8328                 testGetSupportedFeaturesCaseForRtt(featureInfra | featureD2dRtt, false));
8329         assertEquals(featureInfra,
8330                 testGetSupportedFeaturesCaseForRtt(featureInfra | featureD2dRtt, true));
8331         assertEquals(featureInfra | featureD2apRtt,
8332                 testGetSupportedFeaturesCaseForRtt(featureInfra | featureD2apRtt, false));
8333         assertEquals(featureInfra,
8334                 testGetSupportedFeaturesCaseForRtt(featureInfra | featureD2apRtt, true));
8335         assertEquals(featureInfra | featureD2dRtt | featureD2apRtt,
8336                 testGetSupportedFeaturesCaseForRtt(
8337                         featureInfra | featureD2dRtt | featureD2apRtt, false));
8338         assertEquals(featureInfra,
8339                 testGetSupportedFeaturesCaseForRtt(
8340                         featureInfra | featureD2dRtt | featureD2apRtt, true));
8341 
8342         assertEquals(featureLongBits | featureInfra | featureD2dRtt | featureD2apRtt,
8343                 testGetSupportedFeaturesCaseForRtt(
8344                         featureLongBits | featureInfra | featureD2dRtt | featureD2apRtt, false));
8345         assertEquals(featureLongBits | featureInfra,
8346                 testGetSupportedFeaturesCaseForRtt(
8347                         featureLongBits | featureInfra | featureD2dRtt | featureD2apRtt, true));
8348     }
8349 
testGetSupportedFeaturesCaseForMacRandomization( long supportedFeaturesFromWifiNative, boolean apMacRandomizationEnabled, boolean staConnectedMacRandomizationEnabled, boolean p2pMacRandomizationEnabled)8350     private long testGetSupportedFeaturesCaseForMacRandomization(
8351             long supportedFeaturesFromWifiNative, boolean apMacRandomizationEnabled,
8352             boolean staConnectedMacRandomizationEnabled, boolean p2pMacRandomizationEnabled) {
8353         when(mResources.getBoolean(
8354                 R.bool.config_wifi_connected_mac_randomization_supported))
8355                 .thenReturn(staConnectedMacRandomizationEnabled);
8356         when(mResources.getBoolean(
8357                 R.bool.config_wifi_ap_mac_randomization_supported))
8358                 .thenReturn(apMacRandomizationEnabled);
8359         when(mResources.getBoolean(
8360                 R.bool.config_wifi_p2p_mac_randomization_supported))
8361                 .thenReturn(p2pMacRandomizationEnabled);
8362         when(mWifiNative.getSupportedFeatureSet(anyString()))
8363                 .thenReturn(supportedFeaturesFromWifiNative);
8364         mLooper.startAutoDispatch();
8365         long supportedFeatures = mWifiServiceImpl.getSupportedFeatures();
8366         mLooper.stopAutoDispatchAndIgnoreExceptions();
8367         return supportedFeatures;
8368     }
8369 
8370     /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */
8371     @Test
syncGetSupportedFeaturesForMacRandomization()8372     public void syncGetSupportedFeaturesForMacRandomization() {
8373         final long featureStaConnectedMacRandomization =
8374                 WifiManager.WIFI_FEATURE_CONNECTED_RAND_MAC;
8375         final long featureApMacRandomization =
8376                 WifiManager.WIFI_FEATURE_AP_RAND_MAC;
8377         final long featureP2pMacRandomization =
8378                 WifiManager.WIFI_FEATURE_CONNECTED_RAND_MAC;
8379 
8380         assertEquals(featureStaConnectedMacRandomization | featureApMacRandomization
8381                         | featureP2pMacRandomization,
8382                 testGetSupportedFeaturesCaseForMacRandomization(
8383                         featureP2pMacRandomization, true, true, true));
8384         // p2p supported by HAL, but disabled by overlay.
8385         assertEquals(featureStaConnectedMacRandomization | featureApMacRandomization,
8386                 testGetSupportedFeaturesCaseForMacRandomization(
8387                         featureP2pMacRandomization, true, true, false));
8388         assertEquals(featureStaConnectedMacRandomization | featureApMacRandomization,
8389                 testGetSupportedFeaturesCaseForMacRandomization(0, true, true, false));
8390     }
8391 
8392     @Test
getSupportedFeaturesVerboseLoggingThrottled()8393     public void getSupportedFeaturesVerboseLoggingThrottled() {
8394         mWifiServiceImpl.enableVerboseLogging(
8395                 WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED); // this logs
8396         when(mClock.getElapsedSinceBootMillis()).thenReturn(1000L);
8397         testGetSupportedFeaturesCaseForMacRandomization(0, true, true, false);
8398         when(mClock.getElapsedSinceBootMillis()).thenReturn(1001L);
8399         testGetSupportedFeaturesCaseForMacRandomization(0, true, true, false); // should not log
8400         when(mClock.getElapsedSinceBootMillis()).thenReturn(5000L);
8401         testGetSupportedFeaturesCaseForMacRandomization(0, true, true, false);
8402         testGetSupportedFeaturesCaseForMacRandomization(0, true, false, false);
8403         verify(mLog, times(4)).info(any());
8404     }
8405 
8406     /**
8407      * Verifies that syncGetSupportedFeatures() adds capabilities based on interface
8408      * combination.
8409      */
8410     @Test
syncGetSupportedFeaturesForStaApConcurrency()8411     public void syncGetSupportedFeaturesForStaApConcurrency() {
8412         long supportedFeaturesFromWifiNative = WifiManager.WIFI_FEATURE_OWE;
8413         when(mWifiNative.getSupportedFeatureSet(anyString()))
8414                 .thenReturn(supportedFeaturesFromWifiNative);
8415 
8416         when(mActiveModeWarden.isStaApConcurrencySupported())
8417                 .thenReturn(false);
8418         mLooper.startAutoDispatch();
8419         assertEquals(supportedFeaturesFromWifiNative,
8420                         mWifiServiceImpl.getSupportedFeatures());
8421         mLooper.stopAutoDispatchAndIgnoreExceptions();
8422 
8423         when(mActiveModeWarden.isStaApConcurrencySupported())
8424                 .thenReturn(true);
8425         mLooper.startAutoDispatch();
8426         assertEquals(supportedFeaturesFromWifiNative | WifiManager.WIFI_FEATURE_AP_STA,
8427                 mWifiServiceImpl.getSupportedFeatures());
8428         mLooper.stopAutoDispatchAndIgnoreExceptions();
8429     }
8430 
8431     /**
8432      * Verify startRestrictingAutoJoinToSubscriptionId is guarded by NETWORK_SETTINGS
8433      * permission.
8434      */
8435     @Test
testStartTemporarilyDisablingAllNonCarrierMergedWifiPermission()8436     public void testStartTemporarilyDisablingAllNonCarrierMergedWifiPermission() {
8437         assumeTrue(SdkLevel.isAtLeastS());
8438         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8439                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
8440         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
8441                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
8442         try {
8443             mWifiServiceImpl.startRestrictingAutoJoinToSubscriptionId(1);
8444             fail();
8445         } catch (SecurityException e) {
8446             // pass
8447         }
8448     }
8449 
8450     /**
8451      * Verify startRestrictingAutoJoinToSubscriptionId works properly with permission.
8452      */
8453     @Test
testStartTemporarilyDisablingAllNonCarrierMergedWifi()8454     public void testStartTemporarilyDisablingAllNonCarrierMergedWifi() {
8455         assumeTrue(SdkLevel.isAtLeastS());
8456         List<ClientModeManager> cmmList = new ArrayList<>();
8457         ConcreteClientModeManager localOnlyCmm = mock(ConcreteClientModeManager.class);
8458         ConcreteClientModeManager secondaryTransientCmm = mock(ConcreteClientModeManager.class);
8459         when(localOnlyCmm.getRole()).thenReturn(ROLE_CLIENT_LOCAL_ONLY);
8460         when(secondaryTransientCmm.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT);
8461         cmmList.add(mClientModeManager);
8462         cmmList.add(localOnlyCmm);
8463         cmmList.add(secondaryTransientCmm);
8464         when(mActiveModeWarden.getClientModeManagers()).thenReturn(cmmList);
8465         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
8466                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
8467 
8468         mWifiServiceImpl.startRestrictingAutoJoinToSubscriptionId(1);
8469         mLooper.dispatchAll();
8470         verify(mWifiConfigManager).startRestrictingAutoJoinToSubscriptionId(1);
8471         verify(mWifiConnectivityManager).clearCachedCandidates();
8472         verify(localOnlyCmm, never()).disconnect();
8473         verify(secondaryTransientCmm).disconnect();
8474         verify(mClientModeManager).disconnect();
8475     }
8476 
8477     /**
8478      * Verify stopRestrictingAutoJoinToSubscriptionId is guarded by NETWORK_SETTINGS
8479      * and NETWORK_SETUP_WIZARD permission.
8480      */
8481     @Test
testStopTemporarilyDisablingAllNonCarrierMergedWifiPermission()8482     public void testStopTemporarilyDisablingAllNonCarrierMergedWifiPermission() {
8483         assumeTrue(SdkLevel.isAtLeastS());
8484         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8485                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
8486         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
8487                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
8488         try {
8489             mWifiServiceImpl.stopRestrictingAutoJoinToSubscriptionId();
8490             fail();
8491         } catch (SecurityException e) {
8492             // pass
8493         }
8494     }
8495 
8496     /**
8497      * Verify stopRestrictingAutoJoinToSubscriptionId works properly with permission.
8498      */
8499     @Test
testStopTemporarilyDisablingAllNonCarrierMergedWifi()8500     public void testStopTemporarilyDisablingAllNonCarrierMergedWifi() {
8501         assumeTrue(SdkLevel.isAtLeastS());
8502         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8503                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
8504         mWifiServiceImpl.stopRestrictingAutoJoinToSubscriptionId();
8505         mLooper.dispatchAll();
8506         verify(mWifiConfigManager).stopRestrictingAutoJoinToSubscriptionId();
8507     }
8508 
8509     @Test(expected = SecurityException.class)
testGetCountryCodeThrowsException()8510     public void testGetCountryCodeThrowsException() {
8511         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
8512         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
8513                 any(), any(), anyInt(), any())).thenReturn(false);
8514         mWifiServiceImpl.getCountryCode(TEST_PACKAGE_NAME, TEST_FEATURE_ID);
8515     }
8516 
8517     @Test
testGetCountryCode()8518     public void testGetCountryCode() {
8519         // verify get country code with network settings permission.
8520         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
8521         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
8522                 any(), any(), anyInt(), any())).thenReturn(false);
8523         mWifiServiceImpl.getCountryCode(TEST_PACKAGE_NAME, TEST_FEATURE_ID);
8524 
8525         // verify get country code with coarse location permission.
8526         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
8527         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
8528                 any(), any(), anyInt(), any())).thenReturn(true);
8529         mWifiServiceImpl.getCountryCode(TEST_PACKAGE_NAME, TEST_FEATURE_ID);
8530     }
8531 
8532     /**
8533      * Verifies that syncGetSupportedFeatures() adds capabilities based on interface
8534      * combination.
8535      */
8536     @Test
syncGetSupportedFeaturesForStaStaConcurrency()8537     public void syncGetSupportedFeaturesForStaStaConcurrency() {
8538         assumeTrue(SdkLevel.isAtLeastS());
8539 
8540         long supportedFeaturesFromWifiNative = WifiManager.WIFI_FEATURE_OWE;
8541         when(mWifiNative.getSupportedFeatureSet(anyString()))
8542                 .thenReturn(supportedFeaturesFromWifiNative);
8543 
8544         mLooper.startAutoDispatch();
8545         assertEquals(supportedFeaturesFromWifiNative,
8546                 mWifiServiceImpl.getSupportedFeatures());
8547         mLooper.stopAutoDispatchAndIgnoreExceptions();
8548 
8549         when(mActiveModeWarden.isStaStaConcurrencySupportedForLocalOnlyConnections())
8550                 .thenReturn(true);
8551         mLooper.startAutoDispatch();
8552         assertEquals(supportedFeaturesFromWifiNative
8553                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY,
8554                 mWifiServiceImpl.getSupportedFeatures());
8555         mLooper.stopAutoDispatchAndIgnoreExceptions();
8556 
8557         when(mActiveModeWarden.isStaStaConcurrencySupportedForMbb()).thenReturn(true);
8558         mLooper.startAutoDispatch();
8559         assertEquals(supportedFeaturesFromWifiNative
8560                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY
8561                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB,
8562                 mWifiServiceImpl.getSupportedFeatures());
8563         mLooper.stopAutoDispatchAndIgnoreExceptions();
8564 
8565         when(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections())
8566                 .thenReturn(true);
8567         when(mActiveModeWarden.isStaStaConcurrencySupportedForMultiInternet())
8568                 .thenReturn(true);
8569         mLooper.startAutoDispatch();
8570         assertEquals(supportedFeaturesFromWifiNative
8571                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY
8572                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB
8573                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED
8574                         | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET,
8575                 mWifiServiceImpl.getSupportedFeatures());
8576         mLooper.stopAutoDispatchAndIgnoreExceptions();
8577     }
8578 
8579     @Test
testSetScanThrottleEnabledWithNetworkSettingsPermission()8580     public void testSetScanThrottleEnabledWithNetworkSettingsPermission() {
8581         doNothing().when(mContext)
8582                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8583                         eq("WifiService"));
8584         mWifiServiceImpl.setScanThrottleEnabled(true);
8585         mLooper.dispatchAll();
8586         verify(mScanRequestProxy).setScanThrottleEnabled(true);
8587 
8588         mWifiServiceImpl.setScanThrottleEnabled(false);
8589         mLooper.dispatchAll();
8590         verify(mScanRequestProxy).setScanThrottleEnabled(false);
8591     }
8592 
8593     @Test(expected = SecurityException.class)
testSetScanThrottleEnabledWithNoNetworkSettingsPermission()8594     public void testSetScanThrottleEnabledWithNoNetworkSettingsPermission() {
8595         doThrow(new SecurityException()).when(mContext)
8596                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8597                         eq("WifiService"));
8598 
8599         mWifiServiceImpl.setScanThrottleEnabled(true);
8600         mLooper.dispatchAll();
8601         verify(mScanRequestProxy, never()).setScanThrottleEnabled(true);
8602     }
8603 
8604     @Test
testIsScanThrottleEnabled()8605     public void testIsScanThrottleEnabled() {
8606         when(mScanRequestProxy.isScanThrottleEnabled()).thenReturn(true);
8607         mLooper.startAutoDispatch();
8608         assertTrue(mWifiServiceImpl.isScanThrottleEnabled());
8609         mLooper.stopAutoDispatchAndIgnoreExceptions();
8610         verify(mScanRequestProxy).isScanThrottleEnabled();
8611     }
8612 
8613     @Test
testSetAutoWakeupEnabledWithNetworkSettingsPermission()8614     public void testSetAutoWakeupEnabledWithNetworkSettingsPermission() {
8615         doNothing().when(mContext)
8616                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8617                         eq("WifiService"));
8618         mWifiServiceImpl.setAutoWakeupEnabled(true);
8619         mLooper.dispatchAll();
8620         verify(mWakeupController).setEnabled(true);
8621 
8622         mWifiServiceImpl.setAutoWakeupEnabled(false);
8623         mLooper.dispatchAll();
8624         verify(mWakeupController).setEnabled(false);
8625     }
8626 
8627     @Test(expected = SecurityException.class)
testSetAutoWakeupEnabledWithNoNetworkSettingsPermission()8628     public void testSetAutoWakeupEnabledWithNoNetworkSettingsPermission() {
8629         doThrow(new SecurityException()).when(mContext)
8630                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8631                         eq("WifiService"));
8632 
8633         mWifiServiceImpl.setAutoWakeupEnabled(true);
8634         mLooper.dispatchAll();
8635         verify(mWakeupController, never()).setEnabled(true);
8636     }
8637 
8638     @Test
testIsAutoWakeupEnabled()8639     public void testIsAutoWakeupEnabled() {
8640         when(mWakeupController.isEnabled()).thenReturn(true);
8641         mLooper.startAutoDispatch();
8642         assertTrue(mWifiServiceImpl.isAutoWakeupEnabled());
8643         mLooper.stopAutoDispatchAndIgnoreExceptions();
8644         verify(mWakeupController).isEnabled();
8645     }
8646 
8647     @Test
testSetScanAlwaysAvailableWithNetworkSettingsPermission()8648     public void testSetScanAlwaysAvailableWithNetworkSettingsPermission() {
8649         doNothing().when(mContext)
8650                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8651                         eq("WifiService"));
8652         mWifiServiceImpl.setScanAlwaysAvailable(true, TEST_PACKAGE_NAME);
8653         verify(mSettingsStore).handleWifiScanAlwaysAvailableToggled(true);
8654         verify(mActiveModeWarden).scanAlwaysModeChanged();
8655 
8656         mWifiServiceImpl.setScanAlwaysAvailable(false, TEST_PACKAGE_NAME);
8657         verify(mSettingsStore).handleWifiScanAlwaysAvailableToggled(false);
8658         verify(mActiveModeWarden, times(2)).scanAlwaysModeChanged();
8659     }
8660 
8661     @Test(expected = SecurityException.class)
testSetScanAlwaysAvailableWithNoNetworkSettingsPermission()8662     public void testSetScanAlwaysAvailableWithNoNetworkSettingsPermission() {
8663         doThrow(new SecurityException()).when(mContext)
8664                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
8665                         eq("WifiService"));
8666 
8667         mWifiServiceImpl.setScanAlwaysAvailable(true, TEST_PACKAGE_NAME);
8668         verify(mSettingsStore, never()).handleWifiScanAlwaysAvailableToggled(anyBoolean());
8669         verify(mActiveModeWarden, never()).scanAlwaysModeChanged();
8670     }
8671 
8672     @Test
testIsScanAlwaysAvailable()8673     public void testIsScanAlwaysAvailable() {
8674         when(mSettingsStore.isScanAlwaysAvailableToggleEnabled()).thenReturn(true);
8675         assertTrue(mWifiServiceImpl.isScanAlwaysAvailable());
8676         verify(mSettingsStore).isScanAlwaysAvailableToggleEnabled();
8677     }
8678 
createScanResultList()8679     private List<ScanResult> createScanResultList() {
8680         return Collections.singletonList(new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID),
8681                 TEST_SSID, TEST_BSSID, 1245, 0, TEST_CAP, -78, 2450, 1025, 22, 33, 20, 0, 0, true));
8682     }
8683 
sendCountryCodeChangedBroadcast(String countryCode)8684     private void sendCountryCodeChangedBroadcast(String countryCode) {
8685         Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
8686         intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, countryCode);
8687         assertNotNull(mBroadcastReceiverCaptor.getValue());
8688         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
8689     }
8690 
8691     @Test
testCountryCodeBroadcastHanding()8692     public void testCountryCodeBroadcastHanding() {
8693         mWifiServiceImpl.checkAndStartWifi();
8694         mLooper.dispatchAll();
8695         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
8696                 argThat((IntentFilter filter) ->
8697                         filter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)),
8698                 isNull(),
8699                 any(Handler.class));
8700         sendCountryCodeChangedBroadcast("US");
8701         verify(mWifiCountryCode).setTelephonyCountryCodeAndUpdate(any());
8702     }
8703 
8704     @Test
testDumpShouldDumpWakeupController()8705     public void testDumpShouldDumpWakeupController() {
8706         mWifiServiceImpl.checkAndStartWifi();
8707         mLooper.dispatchAll();
8708         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
8709         mLooper.dispatchAll();
8710         verify(mWakeupController).dump(any(), any(), any());
8711     }
8712 
8713     /**
8714      * Test register listener without permission.
8715      */
8716     @Test(expected = SecurityException.class)
testAddSuggestionUserApprovalStatusListenerWithMissingPermission()8717     public void testAddSuggestionUserApprovalStatusListenerWithMissingPermission() {
8718         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
8719                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
8720         mWifiServiceImpl.addSuggestionUserApprovalStatusListener(
8721                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8722     }
8723 
8724     /**
8725      * Test register listener from background user.
8726      */
8727     @Test(expected = SecurityException.class)
testAddSuggestionUserApprovalStatusListenerFromBackgroundUser()8728     public void testAddSuggestionUserApprovalStatusListenerFromBackgroundUser() {
8729         when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
8730                 .thenReturn(false);
8731         mWifiServiceImpl.addSuggestionUserApprovalStatusListener(
8732                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8733     }
8734 
8735     /**
8736      * Test unregister listener from background user.
8737      */
8738     @Test(expected = SecurityException.class)
testRemoveSuggestionUserApprovalStatusListenerFromBackgroundUser()8739     public void testRemoveSuggestionUserApprovalStatusListenerFromBackgroundUser() {
8740         when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
8741                 .thenReturn(false);
8742         mWifiServiceImpl.removeSuggestionUserApprovalStatusListener(
8743                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8744     }
8745 
8746     /**
8747      * Test register listener without listener
8748      */
8749     @Test(expected = NullPointerException.class)
testAddSuggestionUserApprovalStatusListenerWithIllegalArgument()8750     public void testAddSuggestionUserApprovalStatusListenerWithIllegalArgument() {
8751         mWifiServiceImpl.addSuggestionUserApprovalStatusListener(null, TEST_PACKAGE_NAME);
8752     }
8753 
8754     /**
8755      * Test unregister callback without permission.
8756      */
8757     @Test(expected = SecurityException.class)
testUnregisterSuggestionUserApprovalStatusListenerWithMissingPermission()8758     public void testUnregisterSuggestionUserApprovalStatusListenerWithMissingPermission() {
8759         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
8760                 eq(ACCESS_WIFI_STATE), eq("WifiService"));
8761         mWifiServiceImpl.removeSuggestionUserApprovalStatusListener(
8762                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8763     }
8764 
8765     /**
8766      * Test add and remove listener will go to WifiNetworkSuggestionManager
8767      */
8768     @Test
testAddRemoveSuggestionUserApprovalStatusListener()8769     public void testAddRemoveSuggestionUserApprovalStatusListener() {
8770         mWifiServiceImpl.addSuggestionUserApprovalStatusListener(
8771                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8772         mLooper.dispatchAll();
8773         verify(mWifiNetworkSuggestionsManager).addSuggestionUserApprovalStatusListener(
8774                 eq(mSuggestionUserApprovalStatusListener), eq(TEST_PACKAGE_NAME), anyInt());
8775 
8776         mWifiServiceImpl.removeSuggestionUserApprovalStatusListener(
8777                 mSuggestionUserApprovalStatusListener, TEST_PACKAGE_NAME);
8778         mLooper.dispatchAll();
8779         verify(mWifiNetworkSuggestionsManager).removeSuggestionUserApprovalStatusListener(
8780                 eq(mSuggestionUserApprovalStatusListener), eq(TEST_PACKAGE_NAME), anyInt());
8781     }
8782 
8783     @Test
testGetDhcpInfo()8784     public void testGetDhcpInfo() throws Exception {
8785         DhcpResultsParcelable dhcpResultsParcelable = new DhcpResultsParcelable();
8786         dhcpResultsParcelable.leaseDuration = 100;
8787         when(mClientModeManager.syncGetDhcpResultsParcelable()).thenReturn(dhcpResultsParcelable);
8788 
8789         mLooper.startAutoDispatch();
8790         DhcpInfo dhcpInfo = mWifiServiceImpl.getDhcpInfo(TEST_PACKAGE);
8791         mLooper.stopAutoDispatchAndIgnoreExceptions();
8792 
8793         assertEquals(dhcpResultsParcelable.leaseDuration, dhcpInfo.leaseDuration);
8794     }
8795 
8796     @Test
testGetDhcpInfoFromSecondaryCmmFromAppRequestingSecondaryCmm()8797     public void testGetDhcpInfoFromSecondaryCmmFromAppRequestingSecondaryCmm() throws Exception {
8798         DhcpResultsParcelable dhcpResultsParcelable = new DhcpResultsParcelable();
8799         dhcpResultsParcelable.leaseDuration = 100;
8800         ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
8801         when(secondaryCmm.getRequestorWs())
8802                 .thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE));
8803         when(secondaryCmm.syncGetDhcpResultsParcelable()).thenReturn(dhcpResultsParcelable);
8804         when(mActiveModeWarden.getClientModeManagersInRoles(
8805                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
8806                 .thenReturn(Arrays.asList(secondaryCmm));
8807 
8808         mLooper.startAutoDispatch();
8809         DhcpInfo dhcpInfo = mWifiServiceImpl.getDhcpInfo(TEST_PACKAGE);
8810         mLooper.stopAutoDispatchAndIgnoreExceptions();
8811 
8812         assertEquals(dhcpResultsParcelable.leaseDuration, dhcpInfo.leaseDuration);
8813     }
8814 
8815     @Test
testGetDhcpInfoFromPrimaryCmmFromAppNotRequestingSecondaryCmm()8816     public void testGetDhcpInfoFromPrimaryCmmFromAppNotRequestingSecondaryCmm() throws Exception {
8817         DhcpResultsParcelable dhcpResultsParcelable = new DhcpResultsParcelable();
8818         dhcpResultsParcelable.leaseDuration = 100;
8819         when(mClientModeManager.syncGetDhcpResultsParcelable()).thenReturn(dhcpResultsParcelable);
8820         ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
8821         when(secondaryCmm.getRequestorWs())
8822                 .thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME_OTHER));
8823         when(mActiveModeWarden.getClientModeManagersInRoles(
8824                 ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
8825                 .thenReturn(Arrays.asList(secondaryCmm));
8826 
8827         mLooper.startAutoDispatch();
8828         DhcpInfo dhcpInfo = mWifiServiceImpl.getDhcpInfo(TEST_PACKAGE);
8829         mLooper.stopAutoDispatchAndIgnoreExceptions();
8830 
8831         assertEquals(dhcpResultsParcelable.leaseDuration, dhcpInfo.leaseDuration);
8832     }
8833 
8834     @Test
testSetEmergencyScanRequestInProgress()8835     public void testSetEmergencyScanRequestInProgress() throws Exception {
8836         mWifiServiceImpl.setEmergencyScanRequestInProgress(true);
8837         verify(mActiveModeWarden).setEmergencyScanRequestInProgress(true);
8838 
8839         mWifiServiceImpl.setEmergencyScanRequestInProgress(false);
8840         verify(mActiveModeWarden).setEmergencyScanRequestInProgress(false);
8841     }
8842 
8843     @Test
testSetEmergencyScanRequestWithoutPermissionThrowsException()8844     public void testSetEmergencyScanRequestWithoutPermissionThrowsException() throws Exception {
8845         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
8846                 .thenReturn(PackageManager.PERMISSION_DENIED);
8847         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
8848                 eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
8849         try {
8850             mWifiServiceImpl.setEmergencyScanRequestInProgress(true);
8851             fail();
8852         } catch (SecurityException e) { }
8853     }
8854 
8855     @Test
testRemoveAppState()8856     public void testRemoveAppState() throws Exception {
8857         mWifiServiceImpl.removeAppState(TEST_UID, TEST_PACKAGE_NAME);
8858         mLooper.dispatchAll();
8859 
8860         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(TEST_PACKAGE_NAME, TEST_UID);
8861         verify(mWifiNetworkSuggestionsManager).removeApp(TEST_PACKAGE_NAME);
8862         verify(mWifiNetworkFactory).removeUserApprovedAccessPointsForApp(TEST_PACKAGE_NAME);
8863         verify(mPasspointManager).removePasspointProviderWithPackage(TEST_PACKAGE_NAME);
8864     }
8865 
8866     @Test
testRemoveAppStateWithoutPermissionThrowsException()8867     public void testRemoveAppStateWithoutPermissionThrowsException() throws Exception {
8868         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
8869                 eq(Manifest.permission.NETWORK_SETTINGS), any());
8870         try {
8871             mWifiServiceImpl.removeAppState(TEST_UID, TEST_PACKAGE_NAME);
8872             fail();
8873         } catch (SecurityException e) { }
8874     }
8875 
8876     @Test
testNotificationResetWithLocaleChange()8877     public void testNotificationResetWithLocaleChange() {
8878         mWifiServiceImpl.checkAndStartWifi();
8879         mLooper.dispatchAll();
8880         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
8881                 argThat((IntentFilter filter) ->
8882                         filter.hasAction(Intent.ACTION_LOCALE_CHANGED)),
8883                 isNull(),
8884                 any(Handler.class));
8885         verify(mWifiNotificationManager).createNotificationChannels();
8886         clearInvocations(mWifiNotificationManager);
8887 
8888         Intent intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
8889         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
8890         verify(mWifiNotificationManager).createNotificationChannels();
8891         verify(mWifiNetworkSuggestionsManager).resetNotification();
8892         verify(mWifiCarrierInfoManager).resetNotification();
8893         verify(mOpenNetworkNotifier).clearPendingNotification(false);
8894         verify(mWakeupController).resetNotification();
8895     }
8896 
8897     /**
8898      * Verify that a call to setWifiScoringEnabled throws a SecurityException if the caller does
8899      * not have NETWORK_SETTINGS permission.
8900      */
8901     @Test
testSetWifiScoringEnabledThrowsSecurityExceptionOnMissingPermissions()8902     public void testSetWifiScoringEnabledThrowsSecurityExceptionOnMissingPermissions() {
8903         doThrow(new SecurityException()).when(mContext)
8904                 .enforceCallingOrSelfPermission(
8905                 eq(android.Manifest.permission.NETWORK_SETTINGS),
8906                 eq("WifiService"));
8907         try {
8908             mWifiServiceImpl.setWifiScoringEnabled(true);
8909             fail("expected SecurityException");
8910         } catch (SecurityException expected) {
8911         }
8912     }
8913 
8914     /**
8915      * Verify that setWifiScoringEnabled sets the boolean to {@link WifiSettingsStore}.
8916      */
8917     @Test
testSetWifiScoringEnabledGoesToSettingsStore()8918     public void testSetWifiScoringEnabledGoesToSettingsStore() {
8919         mLooper.startAutoDispatch();
8920         mWifiServiceImpl.setWifiScoringEnabled(true);
8921         mLooper.stopAutoDispatch();
8922         verify(mSettingsStore).handleWifiScoringEnabled(true);
8923     }
8924 
8925     @Test
testEnabledTdlsWithMacAddress()8926     public void testEnabledTdlsWithMacAddress() {
8927         mWifiServiceImpl.enableTdlsWithMacAddress(TEST_BSSID, true);
8928         mLooper.dispatchAll();
8929         verify(mClientModeManager).enableTdls(TEST_BSSID, true);
8930 
8931         mWifiServiceImpl.enableTdlsWithMacAddress(TEST_BSSID, false);
8932         mLooper.dispatchAll();
8933         verify(mClientModeManager).enableTdls(TEST_BSSID, false);
8934     }
8935 
8936     /**
8937      * Verify that a call to setOverrideCountryCode() throws a SecurityException if the caller does
8938      * not have the MANAGE_WIFI_COUNTRY_CODE permission.
8939      */
8940     @Test
testSetOverrideCountryCodeThrowsSecurityExceptionOnMissingPermissions()8941     public void testSetOverrideCountryCodeThrowsSecurityExceptionOnMissingPermissions() {
8942         assumeTrue(SdkLevel.isAtLeastS());
8943         doThrow(new SecurityException()).when(mContext)
8944                 .enforceCallingOrSelfPermission(eq(MANAGE_WIFI_COUNTRY_CODE),
8945                         eq("WifiService"));
8946         try {
8947             mWifiServiceImpl.setOverrideCountryCode(TEST_COUNTRY_CODE);
8948             fail("expected SecurityException");
8949         } catch (SecurityException expected) { }
8950     }
8951 
8952     /**
8953      * Verify the call to setOverrideCountryCode() goes to WifiCountryCode
8954      */
8955     @Test
testSetOverrideCountryCode()8956     public void testSetOverrideCountryCode() throws Exception {
8957         assumeTrue(SdkLevel.isAtLeastS());
8958         mWifiServiceImpl.setOverrideCountryCode(TEST_COUNTRY_CODE);
8959         mLooper.dispatchAll();
8960         verify(mWifiCountryCode).setOverrideCountryCode(TEST_COUNTRY_CODE);
8961     }
8962 
8963     /**
8964      * Verify that a call to clearOverrideCountryCode() throws a SecurityException if the caller
8965      * does not have the MANAGE_WIFI_COUNTRY_CODE permission.
8966      */
8967     @Test
testClearOverrideCountryCodeThrowsSecurityExceptionOnMissingPermissions()8968     public void testClearOverrideCountryCodeThrowsSecurityExceptionOnMissingPermissions() {
8969         assumeTrue(SdkLevel.isAtLeastS());
8970         doThrow(new SecurityException()).when(mContext)
8971                 .enforceCallingOrSelfPermission(eq(MANAGE_WIFI_COUNTRY_CODE),
8972                         eq("WifiService"));
8973         try {
8974             mWifiServiceImpl.clearOverrideCountryCode();
8975             fail("expected SecurityException");
8976         } catch (SecurityException expected) { }
8977     }
8978 
8979     /**
8980      * Verify the call to clearOverrideCountryCode() goes to WifiCountryCode
8981      */
8982     @Test
testClearOverrideCountryCode()8983     public void testClearOverrideCountryCode() throws Exception {
8984         assumeTrue(SdkLevel.isAtLeastS());
8985         mWifiServiceImpl.clearOverrideCountryCode();
8986         mLooper.dispatchAll();
8987         verify(mWifiCountryCode).clearOverrideCountryCode();
8988     }
8989 
8990     /**
8991      * Verify that a call to setDefaultCountryCode() throws a SecurityException if the caller does
8992      * not have the MANAGE_WIFI_COUNTRY_CODE permission.
8993      */
8994     @Test
testSetDefaultCountryCodeThrowsSecurityExceptionOnMissingPermissions()8995     public void testSetDefaultCountryCodeThrowsSecurityExceptionOnMissingPermissions() {
8996         assumeTrue(SdkLevel.isAtLeastS());
8997         doThrow(new SecurityException()).when(mContext)
8998                 .enforceCallingOrSelfPermission(eq(MANAGE_WIFI_COUNTRY_CODE),
8999                         eq("WifiService"));
9000         try {
9001             mWifiServiceImpl.setDefaultCountryCode(TEST_COUNTRY_CODE);
9002             fail("expected SecurityException");
9003         } catch (SecurityException expected) { }
9004     }
9005 
9006     /**
9007      * Verify the call to setDefaultCountryCode() goes to WifiCountryCode
9008      */
9009     @Test
testSetDefaultCountryCode()9010     public void testSetDefaultCountryCode() throws Exception {
9011         assumeTrue(SdkLevel.isAtLeastS());
9012         mWifiServiceImpl.setDefaultCountryCode(TEST_COUNTRY_CODE);
9013         mLooper.dispatchAll();
9014         verify(mWifiCountryCode).setDefaultCountryCode(TEST_COUNTRY_CODE);
9015     }
9016 
9017     /**
9018      * Verify that a call to flushPasspointAnqpCache throws a SecurityException if the
9019      * caller does not have any permission.
9020      */
9021     @Test (expected = SecurityException.class)
testFlushPasspointAnqpCacheThrowsSecurityExceptionOnMissingPermissions()9022     public void testFlushPasspointAnqpCacheThrowsSecurityExceptionOnMissingPermissions() {
9023         when(mContext.checkCallingOrSelfPermission(anyString()))
9024                 .thenReturn(PackageManager.PERMISSION_DENIED);
9025         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), anyString())).thenReturn(false);
9026         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), anyString())).thenReturn(false);
9027 
9028         mWifiServiceImpl.flushPasspointAnqpCache(mContext.getPackageName());
9029     }
9030 
9031     /**
9032      * Verifies that the call to testFlushPasspointAnqpCache with DO permission calls Passpoint
9033      * manager to flush the ANQP cache and clear all pending requests.
9034      */
9035     @Test
testFlushPasspointAnqpCacheWithDoPermissions()9036     public void testFlushPasspointAnqpCacheWithDoPermissions() {
9037         when(mContext.checkCallingOrSelfPermission(anyString()))
9038                 .thenReturn(PackageManager.PERMISSION_DENIED);
9039 
9040         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(true);
9041         when(mWifiPermissionsUtil.isProfileOwner(anyInt(),
9042                 eq(TEST_PACKAGE_NAME))).thenReturn(false);
9043         mWifiServiceImpl.flushPasspointAnqpCache(TEST_PACKAGE_NAME);
9044         mLooper.dispatchAll();
9045         verify(mPasspointManager).clearAnqpRequestsAndFlushCache();
9046     }
9047 
9048     /**
9049      * Verifies that the call to testFlushPasspointAnqpCache with PO permission calls Passpoint
9050      * manager to flush the ANQP cache and clear all pending requests.
9051      */
9052     @Test
testFlushPasspointAnqpCacheWithPoPermissions()9053     public void testFlushPasspointAnqpCacheWithPoPermissions() {
9054         when(mContext.checkCallingOrSelfPermission(anyString()))
9055                 .thenReturn(PackageManager.PERMISSION_DENIED);
9056 
9057         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(false);
9058         when(mWifiPermissionsUtil.isProfileOwner(anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(true);
9059         mWifiServiceImpl.flushPasspointAnqpCache(TEST_PACKAGE_NAME);
9060         mLooper.dispatchAll();
9061         verify(mPasspointManager).clearAnqpRequestsAndFlushCache();
9062     }
9063 
9064     /**
9065      * Verifies that the call to testFlushPasspointAnqpCache calls Passpoint manager to flush the
9066      * ANQP cache and clear all pending requests.
9067      */
9068     @Test
testFlushPasspointAnqpCache()9069     public void testFlushPasspointAnqpCache() {
9070         when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS))
9071                 .thenReturn(PackageManager.PERMISSION_GRANTED);
9072         when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(false);
9073         when(mWifiPermissionsUtil.isProfileOwner(anyInt(),
9074                 eq(TEST_PACKAGE_NAME))).thenReturn(false);
9075         mWifiServiceImpl.flushPasspointAnqpCache(TEST_PACKAGE_NAME);
9076         mLooper.dispatchAll();
9077         verify(mPasspointManager).clearAnqpRequestsAndFlushCache();
9078     }
9079 
9080     /**
9081      * Verify that a call to getUsableChannels() throws a SecurityException if the caller does
9082      * not have the LOCATION_HARDWARE permission.
9083      */
9084     @Test
testGetUsableChannelsThrowsSecurityExceptionOnMissingPermissions()9085     public void testGetUsableChannelsThrowsSecurityExceptionOnMissingPermissions() {
9086         assumeTrue(SdkLevel.isAtLeastS());
9087         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
9088         doThrow(new SecurityException()).when(mWifiPermissionsUtil)
9089                 .checkCallersHardwareLocationPermission(anyInt());
9090         try {
9091             mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY);
9092             fail("expected SecurityException");
9093         } catch (SecurityException expected) { }
9094     }
9095 
9096     /**
9097      * Verify the call to isValidBandForGetUsableChannels()
9098      */
9099     @Test
testIsValidBandForGetUsableChannels()9100     public void testIsValidBandForGetUsableChannels() throws Exception {
9101         assumeTrue(SdkLevel.isAtLeastS());
9102         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9103                 WifiScanner.WIFI_BAND_UNSPECIFIED), true);
9104         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9105                 WifiScanner.WIFI_BAND_24_GHZ), true);
9106         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9107                 WifiScanner.WIFI_BAND_5_GHZ), false);
9108         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9109                 WifiScanner.WIFI_BAND_BOTH), false);
9110         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9111                 WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY), false);
9112         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9113                 WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS), false);
9114         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9115                 WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS), true);
9116         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9117                 WifiScanner.WIFI_BAND_BOTH_WITH_DFS), true);
9118         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9119                 WifiScanner.WIFI_BAND_6_GHZ), true);
9120         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9121                 WifiScanner.WIFI_BAND_24_5_6_GHZ), false);
9122         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9123                 WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ), true);
9124         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9125                 WifiScanner.WIFI_BAND_60_GHZ), true);
9126         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9127                 WifiScanner.WIFI_BAND_24_5_6_60_GHZ), false);
9128         assertEquals(WifiServiceImpl.isValidBandForGetUsableChannels(
9129                 WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ), true);
9130     }
9131 
9132     /**
9133      * Verify that a call to getUsableChannels() throws an IllegalArgumentException
9134      * if the band specified is invalid for getAllowedChannels() method.
9135      */
9136     @Test
testGetUsableChannelsThrowsIllegalArgumentExceptionOnInValidBand()9137     public void testGetUsableChannelsThrowsIllegalArgumentExceptionOnInValidBand() {
9138         assumeTrue(SdkLevel.isAtLeastS());
9139         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
9140         when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
9141                 .thenReturn(true);
9142         try {
9143             mWifiServiceImpl.getUsableChannels(WIFI_BAND_5_GHZ, OP_MODE_STA, FILTER_REGULATORY);
9144             fail("expected IllegalArgumentException");
9145         } catch (IllegalArgumentException expected) {
9146         }
9147     }
9148 
9149     /**
9150      * Verify the call to getUsableChannels() goes to WifiNative
9151      */
9152     @Test
testGetUsableChannels()9153     public void testGetUsableChannels() throws Exception {
9154         assumeTrue(SdkLevel.isAtLeastS());
9155         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
9156         when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
9157                 .thenReturn(true);
9158         mLooper.startAutoDispatch();
9159         mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY);
9160         mLooper.stopAutoDispatch();
9161         verify(mWifiNative).getUsableChannels(anyInt(), anyInt(), anyInt());
9162     }
9163 
9164     /**
9165      * Verify that if the caller has NETWORK_SETTINGS permission, and the overlay
9166      * config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW is set, then it can add an
9167      * insecure Enterprise network, with Root CA certificate not set and/or domain name not set.
9168      */
9169     @Test
testAddInsecureEnterpirseNetworkWithNetworkSettingsPerm()9170     public void testAddInsecureEnterpirseNetworkWithNetworkSettingsPerm() throws Exception {
9171         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
9172                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
9173 
9174         // First set flag to not allow
9175         when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(false);
9176         when(mWifiConfigManager.addOrUpdateNetwork(any(),  anyInt(), any(), eq(false))).thenReturn(
9177                 new NetworkUpdateResult(0));
9178 
9179         // Create an insecure Enterprise network
9180         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
9181         config.enterpriseConfig.setCaPath(null);
9182         config.enterpriseConfig.setDomainSuffixMatch(null);
9183 
9184         // Verify operation fails
9185         mLooper.startAutoDispatch();
9186         assertEquals(-1,
9187                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
9188         mLooper.stopAutoDispatchAndIgnoreExceptions();
9189         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
9190 
9191         // Set flag to allow
9192         when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(true);
9193 
9194         // Verify operation succeeds
9195         mLooper.startAutoDispatch();
9196         assertEquals(0,
9197                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
9198         mLooper.stopAutoDispatchAndIgnoreExceptions();
9199         verify(mWifiConfigManager).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
9200     }
9201 
9202 
9203     /**
9204      * Verify that if the caller does NOT have NETWORK_SETTINGS permission, then it cannot add an
9205      * insecure Enterprise network, with Root CA certificate not set and/or domain name not set,
9206      * regardless of the overlay config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW
9207      * value.
9208      */
9209     @Test
testAddInsecureEnterpirseNetworkWithNoNetworkSettingsPerm()9210     public void testAddInsecureEnterpirseNetworkWithNoNetworkSettingsPerm() throws Exception {
9211         // First set flag to not allow
9212         when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(false);
9213 
9214         // Create an insecure Enterprise network
9215         WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
9216         config.enterpriseConfig.setCaPath(null);
9217         config.enterpriseConfig.setDomainSuffixMatch(null);
9218 
9219         // Verify operation fails
9220         mLooper.startAutoDispatch();
9221         assertEquals(-1,
9222                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
9223         mLooper.stopAutoDispatchAndIgnoreExceptions();
9224         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
9225 
9226         // Set flag to allow
9227         when(mWifiGlobals.isInsecureEnterpriseConfigurationAllowed()).thenReturn(true);
9228 
9229         // Verify operation still fails
9230         mLooper.startAutoDispatch();
9231         assertEquals(-1,
9232                 mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
9233         mLooper.stopAutoDispatchAndIgnoreExceptions();
9234         verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(),  anyInt(), any(), eq(false));
9235     }
9236 
setupMultiTypeConfigs( long featureFlags, boolean saeAutoUpgradeEnabled, boolean oweAutoUpgradeEnabled)9237     private List<WifiConfiguration> setupMultiTypeConfigs(
9238             long featureFlags, boolean saeAutoUpgradeEnabled, boolean oweAutoUpgradeEnabled) {
9239         when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn(featureFlags);
9240         when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(saeAutoUpgradeEnabled);
9241         when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(oweAutoUpgradeEnabled);
9242 
9243         List<WifiConfiguration> multiTypeConfigs  = new ArrayList<>();
9244         multiTypeConfigs.add(WifiConfigurationTestUtil.createOpenOweNetwork());
9245         multiTypeConfigs.add(WifiConfigurationTestUtil.createPskSaeNetwork());
9246         multiTypeConfigs.add(WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork());
9247         return multiTypeConfigs;
9248     }
9249 
isSecurityParamsSupported(SecurityParams params, long wifiFeatures)9250     private boolean isSecurityParamsSupported(SecurityParams params, long wifiFeatures) {
9251         switch (params.getSecurityType()) {
9252             case WifiConfiguration.SECURITY_TYPE_SAE:
9253                 return 0 != (wifiFeatures & WifiManager.WIFI_FEATURE_WPA3_SAE);
9254             case WifiConfiguration.SECURITY_TYPE_OWE:
9255                 return 0 != (wifiFeatures & WifiManager.WIFI_FEATURE_OWE);
9256         }
9257         return true;
9258     }
9259 
generateExpectedConfigs( List<WifiConfiguration> testConfigs, boolean saeAutoUpgradeEnabled, boolean oweAutoUpgradeEnabled)9260     private List<WifiConfiguration> generateExpectedConfigs(
9261             List<WifiConfiguration> testConfigs,
9262             boolean saeAutoUpgradeEnabled, boolean oweAutoUpgradeEnabled) {
9263         if (!SdkLevel.isAtLeastS()) {
9264             return testConfigs;
9265         }
9266         WifiConfiguration tmpConfig;
9267         List<WifiConfiguration> expectedConfigs = new ArrayList<>();
9268         tmpConfig = new WifiConfiguration(testConfigs.get(0));
9269         tmpConfig.setSecurityParams(
9270                 SecurityParams.createSecurityParamsBySecurityType(
9271                         WifiConfiguration.SECURITY_TYPE_OPEN));
9272         expectedConfigs.add(tmpConfig);
9273         if (oweAutoUpgradeEnabled) {
9274             tmpConfig = new WifiConfiguration(testConfigs.get(0));
9275             tmpConfig.setSecurityParams(
9276                     SecurityParams.createSecurityParamsBySecurityType(
9277                             WifiConfiguration.SECURITY_TYPE_OWE));
9278             expectedConfigs.add(tmpConfig);
9279         }
9280         tmpConfig = new WifiConfiguration(testConfigs.get(1));
9281         tmpConfig.setSecurityParams(
9282                 SecurityParams.createSecurityParamsBySecurityType(
9283                         WifiConfiguration.SECURITY_TYPE_PSK));
9284         expectedConfigs.add(tmpConfig);
9285         if (saeAutoUpgradeEnabled) {
9286             tmpConfig = new WifiConfiguration(testConfigs.get(1));
9287             tmpConfig.setSecurityParams(
9288                     SecurityParams.createSecurityParamsBySecurityType(
9289                             WifiConfiguration.SECURITY_TYPE_SAE));
9290             expectedConfigs.add(tmpConfig);
9291         }
9292         tmpConfig = new WifiConfiguration(testConfigs.get(2));
9293         tmpConfig.setSecurityParams(
9294                 SecurityParams.createSecurityParamsBySecurityType(
9295                         WifiConfiguration.SECURITY_TYPE_EAP));
9296         expectedConfigs.add(tmpConfig);
9297         tmpConfig = new WifiConfiguration(testConfigs.get(2));
9298         tmpConfig.setSecurityParams(
9299                 SecurityParams.createSecurityParamsBySecurityType(
9300                         WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE));
9301         expectedConfigs.add(tmpConfig);
9302         return expectedConfigs;
9303     }
9304 
9305     /**
9306      * verify multi-type configs are converted to legacy configs in getConfiguredNetworks
9307      * and getPrivilegedConfiguredNetworks when auto-upgrade is enabled.
9308      */
9309     @Test
testGetConfiguredNetworksForMultiTypeConfigs()9310     public void testGetConfiguredNetworksForMultiTypeConfigs() {
9311         long featureFlags = WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE;
9312         List<WifiConfiguration> testConfigs = setupMultiTypeConfigs(
9313                 featureFlags, true, true);
9314         when(mWifiConfigManager.getSavedNetworks(anyInt()))
9315                 .thenReturn(testConfigs);
9316         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
9317                 .thenReturn(testConfigs);
9318         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
9319                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
9320 
9321         mLooper.startAutoDispatch();
9322         ParceledListSlice<WifiConfiguration> configs =
9323                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
9324         ParceledListSlice<WifiConfiguration> privilegedConfigs =
9325                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
9326                         mExtras);
9327         mLooper.stopAutoDispatchAndIgnoreExceptions();
9328 
9329         List<WifiConfiguration> expectedConfigs = generateExpectedConfigs(
9330                 testConfigs, true, true);
9331         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9332                 expectedConfigs, configs.getList());
9333         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9334                 expectedConfigs, privilegedConfigs.getList());
9335     }
9336 
9337     /**
9338      * verify multi-type configs are converted to legacy configs in getConfiguredNetworks
9339      * and getPrivilegedConfiguredNetworks when auto-upgrade is not enabled.
9340      */
9341     @Test
testGetConfiguredNetworksForMultiTypeConfigsWithoutAutoUpgradeEnabled()9342     public void testGetConfiguredNetworksForMultiTypeConfigsWithoutAutoUpgradeEnabled() {
9343         long featureFlags = WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE;
9344         List<WifiConfiguration> testConfigs = setupMultiTypeConfigs(
9345                 featureFlags, false, false);
9346         when(mWifiConfigManager.getSavedNetworks(anyInt()))
9347                 .thenReturn(testConfigs);
9348         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
9349                 .thenReturn(testConfigs);
9350         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
9351                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
9352 
9353         mLooper.startAutoDispatch();
9354         ParceledListSlice<WifiConfiguration> configs =
9355                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
9356         ParceledListSlice<WifiConfiguration> privilegedConfigs =
9357                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
9358                         mExtras);
9359         mLooper.stopAutoDispatchAndIgnoreExceptions();
9360 
9361         List<WifiConfiguration> expectedConfigs = generateExpectedConfigs(
9362                 testConfigs, false, false);
9363         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9364                 expectedConfigs, configs.getList());
9365         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9366                 expectedConfigs, privilegedConfigs.getList());
9367     }
9368 
9369     /**
9370      * verify multi-type configs are converted to legacy configs in getConfiguredNetworks
9371      * and getPrivilegedConfiguredNetworks when security types are not supported.
9372      */
9373     @Test
testGetConfiguredNetworksForMultiTypeConfigsWithoutHwSupport()9374     public void testGetConfiguredNetworksForMultiTypeConfigsWithoutHwSupport() {
9375         long featureFlags = 0L;
9376         List<WifiConfiguration> testConfigs = setupMultiTypeConfigs(
9377                 featureFlags, true, true);
9378         when(mWifiConfigManager.getSavedNetworks(anyInt()))
9379                 .thenReturn(testConfigs);
9380         when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
9381                 .thenReturn(testConfigs);
9382         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
9383                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
9384 
9385         mLooper.startAutoDispatch();
9386         ParceledListSlice<WifiConfiguration> configs =
9387                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID, false);
9388         ParceledListSlice<WifiConfiguration> privilegedConfigs =
9389                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE, TEST_FEATURE_ID,
9390                         mExtras);
9391         mLooper.stopAutoDispatchAndIgnoreExceptions();
9392 
9393         List<WifiConfiguration> expectedConfigs = generateExpectedConfigs(
9394                 testConfigs, true, true);
9395         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9396                 expectedConfigs, configs.getList());
9397         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
9398                 expectedConfigs, privilegedConfigs.getList());
9399     }
9400 
trySetTargetSdkToT()9401     private void trySetTargetSdkToT() {
9402         if (SdkLevel.isAtLeastT()) {
9403             when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
9404                     eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(false);
9405         }
9406     }
9407 
9408     @Test (expected = SecurityException.class)
testGetPrivilegedConnectedNetworkNoPermission()9409     public void testGetPrivilegedConnectedNetworkNoPermission() {
9410         trySetTargetSdkToT();
9411         if (SdkLevel.isAtLeastT()) {
9412             doThrow(new SecurityException())
9413                     .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
9414                             any(), anyBoolean(), any());
9415         } else {
9416             doThrow(new SecurityException()).when(mWifiPermissionsUtil)
9417                     .enforceCanAccessScanResults(any(), any(), anyInt(), any());
9418         }
9419 
9420         mWifiServiceImpl.getPrivilegedConnectedNetwork(TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
9421         mLooper.dispatchAll();
9422     }
9423 
9424     @Test
testGetPrivilegedConnectedNetworkNotConnected()9425     public void testGetPrivilegedConnectedNetworkNotConnected() {
9426         trySetTargetSdkToT();
9427         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(new WifiInfo());
9428 
9429         mLooper.startAutoDispatch();
9430         assertNull(mWifiServiceImpl.getPrivilegedConnectedNetwork(
9431                 TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras));
9432         mLooper.stopAutoDispatchAndIgnoreExceptions();
9433 
9434         if (SdkLevel.isAtLeastT()) {
9435             verify(mWifiPermissionsUtil).enforceNearbyDevicesPermission(any(), eq(true), any());
9436         } else {
9437             verify(mWifiPermissionsUtil).enforceCanAccessScanResults(any(), any(), anyInt(), any());
9438         }
9439     }
9440 
9441     @Test
testGetPrivilegedConnectedNetworkSuccess()9442     public void testGetPrivilegedConnectedNetworkSuccess() {
9443         // mock testConfig as the currently connected network
9444         trySetTargetSdkToT();
9445         WifiConfiguration testConfig = WifiConfigurationTestUtil.createPskSaeNetwork();
9446         testConfig.networkId = TEST_NETWORK_ID;
9447         testConfig.setRandomizedMacAddress(TEST_FACTORY_MAC_ADDR);
9448         WifiInfo wifiInfo = new WifiInfo();
9449         wifiInfo.setNetworkId(testConfig.networkId);
9450         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
9451         when(mWifiConfigManager.getConfiguredNetworkWithPassword(testConfig.networkId)).thenReturn(
9452                 testConfig);
9453 
9454         mLooper.startAutoDispatch();
9455         WifiConfiguration result = mWifiServiceImpl.getPrivilegedConnectedNetwork(
9456                 TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
9457         mLooper.stopAutoDispatchAndIgnoreExceptions();
9458 
9459         if (SdkLevel.isAtLeastT()) {
9460             verify(mWifiPermissionsUtil).enforceNearbyDevicesPermission(any(), eq(true), any());
9461         } else {
9462             verify(mWifiPermissionsUtil).enforceCanAccessScanResults(any(), any(), anyInt(), any());
9463         }
9464         verify(mWifiConfigManager).getConfiguredNetworkWithPassword(testConfig.networkId);
9465         // verify the credentials match
9466         assertEquals(testConfig.networkId, result.networkId);
9467         assertEquals(testConfig.SSID, result.SSID);
9468         assertEquals(testConfig.preSharedKey, result.preSharedKey);
9469         // verify the randomized MAC address is filtered out
9470         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, result.getRandomizedMacAddress().toString());
9471     }
9472 
9473     /**
9474      * Verify that a call to isWifiPasspointEnabled throws a SecurityException if the
9475      * caller does not have the ACCESS_WIFI_STATE permission.
9476      */
9477     @Test (expected = SecurityException.class)
testIsWifiPasspointEnabledWithoutPermissions()9478     public void testIsWifiPasspointEnabledWithoutPermissions() {
9479         doThrow(new SecurityException()).when(mContext)
9480                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
9481                         eq("WifiService"));
9482 
9483         mWifiServiceImpl.isWifiPasspointEnabled();
9484     }
9485 
9486     /**
9487      * Verify that the call to setWifiPasspointEnabled is not redirected to
9488      * specific API when the caller doesn't have
9489      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
9490      */
9491     @Test(expected = SecurityException.class)
testSetWifiPasspointEnabledWithoutPermissions()9492     public void testSetWifiPasspointEnabledWithoutPermissions() {
9493         mLooper.startAutoDispatch();
9494         mWifiServiceImpl.setWifiPasspointEnabled(false);
9495         mLooper.stopAutoDispatchAndIgnoreExceptions();
9496     }
9497 
9498     /**
9499      * Verify that the call to setWifiPasspointEnabled is redirected to
9500      * specific API when the caller have
9501      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
9502      */
9503     @Test
testSetWifiPasspointEnabledWithPermissions()9504     public void testSetWifiPasspointEnabledWithPermissions() {
9505         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
9506                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
9507         mLooper.startAutoDispatch();
9508         mWifiServiceImpl.setWifiPasspointEnabled(false);
9509         mLooper.dispatchAll();
9510         mLooper.stopAutoDispatchAndIgnoreExceptions();
9511         verify(mPasspointManager).setWifiPasspointEnabled(false);
9512     }
9513 
9514     @Test(expected = SecurityException.class)
testSetScreenOnScanSchedule_NoPermission()9515     public void testSetScreenOnScanSchedule_NoPermission() {
9516         assumeTrue(SdkLevel.isAtLeastT());
9517         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9518                 .thenReturn(false);
9519         mWifiServiceImpl.setScreenOnScanSchedule(null, null);
9520     }
9521 
9522     @Test(expected = IllegalArgumentException.class)
testSetScreenOnScanSchedule_BadInput1()9523     public void testSetScreenOnScanSchedule_BadInput1() {
9524         assumeTrue(SdkLevel.isAtLeastT());
9525         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9526                 .thenReturn(true);
9527         // test that both arrays need to be null or non-null. Never one null one non-null.
9528         mWifiServiceImpl.setScreenOnScanSchedule(null, new int[] {1});
9529     }
9530 
9531     @Test(expected = IllegalArgumentException.class)
testSetScreenOnScanSchedule_BadInput2()9532     public void testSetScreenOnScanSchedule_BadInput2() {
9533         assumeTrue(SdkLevel.isAtLeastT());
9534         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9535                 .thenReturn(true);
9536         // test that the input should not be empty arrays.
9537         mWifiServiceImpl.setScreenOnScanSchedule(new int[0], new int[0]);
9538     }
9539 
9540     @Test
testSetScreenOnScanSchedule_Success()9541     public void testSetScreenOnScanSchedule_Success() {
9542         assumeTrue(SdkLevel.isAtLeastT());
9543         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9544                 .thenReturn(true);
9545         int[] expectedSchedule = new int[] {20, 40, 80};
9546         int[] expectedType = new int[] {2, 2, 1};
9547         mWifiServiceImpl.setScreenOnScanSchedule(expectedSchedule, expectedType);
9548         mLooper.dispatchAll();
9549         verify(mWifiConnectivityManager).setExternalScreenOnScanSchedule(
9550                 expectedSchedule, expectedType);
9551         verify(mLastCallerInfoManager).put(eq(WifiManager.API_SET_SCAN_SCHEDULE), anyInt(),
9552                 anyInt(), anyInt(), any(), eq(true));
9553 
9554         mWifiServiceImpl.setScreenOnScanSchedule(null, null);
9555         mLooper.dispatchAll();
9556         verify(mWifiConnectivityManager).setExternalScreenOnScanSchedule(null, null);
9557         verify(mLastCallerInfoManager).put(eq(WifiManager.API_SET_SCAN_SCHEDULE), anyInt(),
9558                 anyInt(), anyInt(), any(), eq(false));
9559     }
9560 
9561     @Test
testSetOneShotScreenOnConnectivityScanDelayMillis()9562     public void testSetOneShotScreenOnConnectivityScanDelayMillis() {
9563         assumeTrue(SdkLevel.isAtLeastT());
9564         int delayMs = 1234;
9565 
9566         // verify permission checks
9567         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9568                 .thenReturn(false);
9569         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt()))
9570                 .thenReturn(false);
9571         assertThrows(SecurityException.class,
9572                 () -> mWifiServiceImpl.setOneShotScreenOnConnectivityScanDelayMillis(delayMs));
9573 
9574         // verify correct input
9575         when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
9576                 .thenReturn(true);
9577         assertThrows(IllegalArgumentException.class,
9578                 () -> mWifiServiceImpl.setOneShotScreenOnConnectivityScanDelayMillis(-1));
9579 
9580         // verify correct call
9581         mWifiServiceImpl.setOneShotScreenOnConnectivityScanDelayMillis(delayMs);
9582         mLooper.dispatchAll();
9583         verify(mWifiConnectivityManager).setOneShotScreenOnConnectivityScanDelayMillis(delayMs);
9584     }
9585 
9586     @Test(expected = SecurityException.class)
testSetExternalPnoScanRequest_NoPermission()9587     public void testSetExternalPnoScanRequest_NoPermission() {
9588         assumeTrue(SdkLevel.isAtLeastT());
9589         IPnoScanResultsCallback callback = mock(IPnoScanResultsCallback.class);
9590         List<WifiSsid> ssids = new ArrayList<>();
9591         ssids.add(WifiSsid.fromString("\"TEST_SSID_1\""));
9592         int[] frequencies = new int[] {TEST_AP_FREQUENCY};
9593 
9594         mWifiServiceImpl.setExternalPnoScanRequest(mAppBinder, callback, ssids, frequencies,
9595                 TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9596     }
9597 
9598     @Test
testSetExternalPnoScanRequest_Success()9599     public void testSetExternalPnoScanRequest_Success() throws Exception {
9600         assumeTrue(SdkLevel.isAtLeastT());
9601         when(mWifiNative.getSupportedFeatureSet(anyString()))
9602                 .thenReturn(WifiManager.WIFI_FEATURE_PNO);
9603         when(mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(
9604                 anyInt())).thenReturn(true);
9605         when(mWifiPermissionsUtil.checkCallersLocationPermission(
9606                 any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
9607         IPnoScanResultsCallback callback = mock(IPnoScanResultsCallback.class);
9608         List<WifiSsid> ssids = new ArrayList<>();
9609         ssids.add(WifiSsid.fromString("\"TEST_SSID_1\""));
9610         int[] frequencies = new int[] {TEST_AP_FREQUENCY};
9611 
9612         mWifiServiceImpl.setExternalPnoScanRequest(mAppBinder, callback, ssids, frequencies,
9613                 TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9614         mLooper.dispatchAll();
9615         verify(mWifiConnectivityManager).setExternalPnoScanRequest(anyInt(), any(), any(),
9616                 eq(callback), eq(ssids), eq(frequencies));
9617     }
9618 
9619     @Test
testSetExternalPnoScanRequest_PnoNotSupported()9620     public void testSetExternalPnoScanRequest_PnoNotSupported() throws Exception {
9621         assumeTrue(SdkLevel.isAtLeastT());
9622         when(mWifiNative.getSupportedFeatureSet(anyString())).thenReturn(0L);
9623         when(mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(
9624                 anyInt())).thenReturn(true);
9625         when(mWifiPermissionsUtil.checkCallersLocationPermission(
9626                 any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
9627         IPnoScanResultsCallback callback = mock(IPnoScanResultsCallback.class);
9628         List<WifiSsid> ssids = new ArrayList<>();
9629         ssids.add(WifiSsid.fromString("\"TEST_SSID_1\""));
9630         int[] frequencies = new int[] {TEST_AP_FREQUENCY};
9631 
9632         mWifiServiceImpl.setExternalPnoScanRequest(mAppBinder, callback, ssids, frequencies,
9633                 TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9634         mLooper.dispatchAll();
9635         verify(callback).onRegisterFailed(WifiManager.PnoScanResultsCallback
9636                 .REGISTER_PNO_CALLBACK_PNO_NOT_SUPPORTED);
9637     }
9638 
9639     @Test
testClearExternalPnoScanRequest()9640     public void testClearExternalPnoScanRequest() {
9641         assumeTrue(SdkLevel.isAtLeastT());
9642 
9643         mWifiServiceImpl.clearExternalPnoScanRequest();
9644         mLooper.dispatchAll();
9645         verify(mWifiConnectivityManager).clearExternalPnoScanRequest(anyInt());
9646     }
9647 
9648     @Test
testGetLastCallerInfoForApi_Exceptions()9649     public void testGetLastCallerInfoForApi_Exceptions() {
9650         // good inputs should result in no exceptions.
9651         ILastCallerListener listener = mock(ILastCallerListener.class);
9652         // null listener ==> IllegalArgumentException
9653         assertThrows(IllegalArgumentException.class,
9654                 () -> mWifiServiceImpl.getLastCallerInfoForApi(
9655                         WifiManager.API_WIFI_ENABLED, null));
9656 
9657         // invalid ApiType ==> IllegalArgumentException
9658         assertThrows(IllegalArgumentException.class,
9659                 () -> mWifiServiceImpl.getLastCallerInfoForApi(WifiManager.API_MAX + 1, listener));
9660 
9661         // No permission ==> SecurityException
9662         assertThrows(SecurityException.class,
9663                 () -> mWifiServiceImpl.getLastCallerInfoForApi(
9664                         WifiManager.API_WIFI_ENABLED, listener));
9665     }
9666 
9667     @Test
testGetLastCallerInfoForApi_GoodCase()9668     public void testGetLastCallerInfoForApi_GoodCase() throws RemoteException {
9669         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
9670         ILastCallerListener listener = mock(ILastCallerListener.class);
9671         LastCallerInfoManager.LastCallerInfo expected =
9672                 new LastCallerInfoManager.LastCallerInfo(0, 1, 2, TEST_PACKAGE_NAME, true);
9673         when(mLastCallerInfoManager.get(WifiManager.API_WIFI_ENABLED)).thenReturn(expected);
9674 
9675         InOrder inOrder = inOrder(listener);
9676         mWifiServiceImpl.getLastCallerInfoForApi(WifiManager.API_WIFI_ENABLED, listener);
9677         mLooper.dispatchAll();
9678         inOrder.verify(listener).onResult(TEST_PACKAGE_NAME, true);
9679 
9680         // Verify null is returned as packageName if there's no information about this ApiType.
9681         mWifiServiceImpl.getLastCallerInfoForApi(WifiManager.API_SOFT_AP, listener);
9682         mLooper.dispatchAll();
9683         inOrder.verify(listener).onResult(null, false);
9684     }
9685 
9686     /**
9687      * Verify that a call to registerDriverCountryCodeChangedListener throws a SecurityException
9688      * if the caller doesnot have ACCESS_COARSE_LOCATION permission.
9689      */
9690     @Test(expected = SecurityException.class)
registerDriverCountryCodeChangedListenerThrowsSecurityExceptionWithoutPermission()9691     public void registerDriverCountryCodeChangedListenerThrowsSecurityExceptionWithoutPermission() {
9692         doThrow(new SecurityException())
9693                 .when(mWifiPermissionsUtil).enforceCoarseLocationPermission(eq(TEST_PACKAGE_NAME),
9694                                                                       eq(TEST_FEATURE_ID),
9695                                                                       anyInt());
9696         mWifiServiceImpl.registerDriverCountryCodeChangedListener(
9697                 mIOnWifiDriverCountryCodeChangedListener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9698     }
9699 
9700     /**
9701      * Verify that a call registerDriverCountryCodeChangedListener throws an
9702      * IllegalArgumentException if the parameters are not provided.
9703      */
9704     @Test
registerDriverCountryCodeChangedListenerThrowsIllegalArgumentException()9705     public void registerDriverCountryCodeChangedListenerThrowsIllegalArgumentException() {
9706         try {
9707             mWifiServiceImpl.registerDriverCountryCodeChangedListener(
9708                     null, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9709             fail("expected IllegalArgumentException");
9710         } catch (IllegalArgumentException expected) {
9711         }
9712     }
9713 
9714     /**
9715      * Verifies that we handle driver country code changed listener registration failure if we
9716      * encounter an exception while linking to death.
9717      */
9718     @Test
registerDriverCountryCodeChangedListenerFailureOnLinkToDeath()9719     public void registerDriverCountryCodeChangedListenerFailureOnLinkToDeath() throws Exception {
9720         doThrow(new RemoteException())
9721                 .when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
9722         mWifiServiceImpl.registerDriverCountryCodeChangedListener(
9723                 mIOnWifiDriverCountryCodeChangedListener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9724         mLooper.dispatchAll();
9725         verify(mIOnWifiDriverCountryCodeChangedListener, never())
9726                 .onDriverCountryCodeChanged(anyString());
9727     }
9728 
9729     /**
9730      * Verify that a call to registerDriverCountryCodeChangedListener succeeded.
9731      */
verifyRegisterDriverCountryCodeChangedListenerSucceededAndTriggerListener( IOnWifiDriverCountryCodeChangedListener listener)9732     private void verifyRegisterDriverCountryCodeChangedListenerSucceededAndTriggerListener(
9733             IOnWifiDriverCountryCodeChangedListener listener)
9734             throws Exception {
9735         doNothing()
9736                 .when(mWifiPermissionsUtil).enforceCoarseLocationPermission(eq(TEST_PACKAGE_NAME),
9737                                                                       eq(TEST_FEATURE_ID),
9738                                                                       anyInt());
9739         when(mWifiCountryCode.getCurrentDriverCountryCode()).thenReturn(TEST_COUNTRY_CODE);
9740         mWifiServiceImpl.registerDriverCountryCodeChangedListener(
9741                 listener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
9742         mLooper.dispatchAll();
9743         verify(listener)
9744                 .onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
9745     }
9746 
9747     /**
9748      * Verify that DriverCountryCodeChanged will be dropped if register permission was removed.
9749      */
9750     @Test
testDriverCountryCodeChangedDropWhenRegisterPermissionRemoved()9751     public void testDriverCountryCodeChangedDropWhenRegisterPermissionRemoved() throws Exception {
9752         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
9753                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), anyInt(), any())).thenReturn(true);
9754         verifyRegisterDriverCountryCodeChangedListenerSucceededAndTriggerListener(
9755                 mIOnWifiDriverCountryCodeChangedListener);
9756         mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_NEW_COUNTRY_CODE);
9757         mLooper.dispatchAll();
9758         verify(mIOnWifiDriverCountryCodeChangedListener)
9759                 .onDriverCountryCodeChanged(TEST_NEW_COUNTRY_CODE);
9760         // remove permission
9761         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
9762                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), anyInt(), any())).thenReturn(false);
9763         reset(mIOnWifiDriverCountryCodeChangedListener);
9764         mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
9765         mLooper.dispatchAll();
9766         verify(mIOnWifiDriverCountryCodeChangedListener, never())
9767                 .onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
9768     }
9769 
9770     /**
9771      * Verify that unregisterDriverCountryCodeChangedListener removes listener from registered
9772      * listener list
9773      */
9774     @Test
unregisterDriverCountryCodeChangedListenerRemovesListener()9775     public void unregisterDriverCountryCodeChangedListenerRemovesListener() throws Exception {
9776         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
9777                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), anyInt(), any())).thenReturn(true);
9778         verifyRegisterDriverCountryCodeChangedListenerSucceededAndTriggerListener(
9779                 mIOnWifiDriverCountryCodeChangedListener);
9780         mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_NEW_COUNTRY_CODE);
9781         mLooper.dispatchAll();
9782         verify(mIOnWifiDriverCountryCodeChangedListener)
9783                 .onDriverCountryCodeChanged(TEST_NEW_COUNTRY_CODE);
9784         mWifiServiceImpl.unregisterDriverCountryCodeChangedListener(
9785                 mIOnWifiDriverCountryCodeChangedListener);
9786         mLooper.dispatchAll();
9787         reset(mIOnWifiDriverCountryCodeChangedListener);
9788         mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
9789         mLooper.dispatchAll();
9790         verify(mIOnWifiDriverCountryCodeChangedListener, never())
9791                 .onDriverCountryCodeChanged(anyString());
9792     }
9793 
9794 
9795     /**
9796      * Verify that onFailed is called when enabling Lohs with non-supported configuration.
9797      */
9798     @Test
testFailureCallbacksTriggeredWhenSoftApFailsBecauseNonSupportedConfiguration()9799     public void testFailureCallbacksTriggeredWhenSoftApFailsBecauseNonSupportedConfiguration()
9800             throws Exception {
9801         when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
9802         setupForCustomLohs();
9803         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
9804         SoftApConfiguration customizedConfig = new SoftApConfiguration.Builder(lohsConfig)
9805                 .setBand(SoftApConfiguration.BAND_6GHZ)
9806                 .setPassphrase("thisIsABadPassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
9807                 .build();
9808         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
9809                 any(), any(), any())).thenReturn(customizedConfig);
9810         // Expect the result is registered but it should get failure because non-supported
9811         // configuration
9812         int result = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME,
9813                 TEST_FEATURE_ID, customizedConfig, mExtras);
9814         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
9815         mLooper.dispatchAll();
9816         verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
9817     }
9818     /**
9819      * Registers a soft AP callback, then verifies that the current soft AP state and num clients
9820      * are sent to caller immediately after callback is registered.
9821      */
registerLohsSoftApCallbackAndVerify(ISoftApCallback callback, Bundle bundle)9822     private void registerLohsSoftApCallbackAndVerify(ISoftApCallback callback, Bundle bundle)
9823             throws Exception {
9824         mWifiServiceImpl.registerLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, bundle);
9825         mLooper.dispatchAll();
9826         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
9827         verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
9828                 new HashMap<String, SoftApInfo>(),
9829                 new HashMap<String, List<WifiClient>>(), false, true);
9830         verify(mClientSoftApCallback).onCapabilityChanged(
9831                 ApConfigUtil.updateCapabilityFromResource(mContext));
9832         // Don't need to invoke callback when register.
9833         verify(mClientSoftApCallback, never()).onBlockedClientConnecting(any(), anyInt());
9834     }
9835 
9836     /**
9837      * Verify that unregisterLocalOnlyHotspotSoftApCallback removes callback from registered
9838      * callbacks list.
9839      */
9840     @Test
unregisterLohsSoftApCallbackRemovesCallback()9841     public void unregisterLohsSoftApCallbackRemovesCallback() throws Exception {
9842         assumeTrue(SdkLevel.isAtLeastT());
9843         registerLohsSoftApCallbackAndVerify(mClientSoftApCallback, mExtras);
9844 
9845         mWifiServiceImpl.unregisterLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, mExtras);
9846         mLooper.dispatchAll();
9847 
9848         reset(mClientSoftApCallback);
9849         mLohsApCallback.onConnectedClientsOrInfoChanged(
9850                 mTestSoftApInfos, mTestSoftApClients, false);
9851         mLooper.dispatchAll();
9852         verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
9853                 any(), any(), anyBoolean(), anyBoolean());
9854     }
9855 
9856     /**
9857      * Verify that unregisterLocalOnlyHotspotSoftApCallback is no-op if callback not registered.
9858      */
9859     @Test
unregisterLohsSoftApCallbackDoesNotRemoveCallbackIfCallbackNotMatching()9860     public void unregisterLohsSoftApCallbackDoesNotRemoveCallbackIfCallbackNotMatching()
9861             throws Exception {
9862         assumeTrue(SdkLevel.isAtLeastT());
9863         registerLohsSoftApCallbackAndVerify(mClientSoftApCallback, mExtras);
9864 
9865         mWifiServiceImpl.unregisterLocalOnlyHotspotSoftApCallback(mAnotherSoftApCallback, mExtras);
9866         mLooper.dispatchAll();
9867         mLohsApCallback.onConnectedClientsOrInfoChanged(
9868                 mTestSoftApInfos, mTestSoftApClients, false);
9869         mLooper.dispatchAll();
9870         verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
9871                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(false));
9872     }
9873 
9874     /**
9875      * Registers two lohs callbacks, remove one then verify the right callback is being called
9876      * on events.
9877      */
9878     @Test
correctLohsCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne()9879     public void correctLohsCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne()
9880             throws Exception {
9881         assumeTrue(SdkLevel.isAtLeastT());
9882         WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"),
9883                 WIFI_IFACE_NAME2);
9884         registerLohsSoftApCallbackAndVerify(mClientSoftApCallback, mExtras);
9885         mLooper.dispatchAll();
9886 
9887         reset(mClientSoftApCallback);
9888         when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
9889         // Change state from default before registering the second callback
9890         mLohsApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
9891         mLohsApCallback.onConnectedClientsOrInfoChanged(
9892                 mTestSoftApInfos, mTestSoftApClients, false);
9893         mLohsApCallback.onBlockedClientConnecting(testWifiClient, 0);
9894 
9895 
9896         // Register another callback and verify the new state is returned in the immediate callback
9897         mWifiServiceImpl.registerLocalOnlyHotspotSoftApCallback(mAnotherSoftApCallback, mExtras);
9898         mLooper.dispatchAll();
9899         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
9900         verify(mAnotherSoftApCallback).onConnectedClientsOrInfoChanged(
9901                 eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
9902         // Verify only first callback will receive onBlockedClientConnecting since it call after
9903         // first callback register but before another callback register.
9904         verify(mClientSoftApCallback).onBlockedClientConnecting(testWifiClient, 0);
9905         verify(mAnotherSoftApCallback, never()).onBlockedClientConnecting(testWifiClient, 0);
9906 
9907         // unregister the fisrt callback
9908         mWifiServiceImpl.unregisterLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, mExtras);
9909         mLooper.dispatchAll();
9910 
9911         // Update soft AP state and verify the remaining callback receives the event
9912         mLohsApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
9913                 SAP_START_FAILURE_NO_CHANNEL);
9914         mLooper.dispatchAll();
9915         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
9916                 SAP_START_FAILURE_NO_CHANNEL);
9917         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
9918                 SAP_START_FAILURE_NO_CHANNEL);
9919     }
9920 
9921     /**
9922      * Verify that wifi service registers for lohs callers BinderDeath event
9923      */
9924     @Test
registersForBinderDeathOnRegisterLohsSoftApCallback()9925     public void registersForBinderDeathOnRegisterLohsSoftApCallback() throws Exception {
9926         assumeTrue(SdkLevel.isAtLeastT());
9927         registerLohsSoftApCallbackAndVerify(mClientSoftApCallback, mExtras);
9928         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
9929     }
9930 
9931     /**
9932      * Verify that we un-register the lohs soft AP callback on receiving BinderDied event.
9933      */
9934     @Test
unregistersLohsSoftApCallbackOnBinderDied()9935     public void unregistersLohsSoftApCallbackOnBinderDied() throws Exception {
9936         assumeTrue(SdkLevel.isAtLeastT());
9937         ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
9938                 ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
9939         registerLohsSoftApCallbackAndVerify(mClientSoftApCallback, mExtras);
9940         verify(mAppBinder).linkToDeath(drCaptor.capture(), anyInt());
9941 
9942         drCaptor.getValue().binderDied();
9943         mLooper.dispatchAll();
9944         reset(mClientSoftApCallback);
9945         // Verify callback is removed from the list as well
9946         Map<String, List<WifiClient>> mTestSoftApClients = mock(Map.class);
9947         Map<String, SoftApInfo> mTestSoftApInfos = mock(Map.class);
9948         mLohsApCallback.onConnectedClientsOrInfoChanged(
9949                 mTestSoftApInfos, mTestSoftApClients, false);
9950         mLooper.dispatchAll();
9951         verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
9952                 any(), any(), anyBoolean(), anyBoolean());
9953     }
9954 
9955     /**
9956      * Verify that a call to registerLocalOnlyHotspotSoftApCallback throws a SecurityException
9957      * if the caller target Android T or later and does not have nearby devices permission.
9958      */
9959     @Test(expected = SecurityException.class)
testRegisterLocalOnlyHotspotSoftApCallbackThrowsExceptionWithoutPermissionOnT()9960     public void testRegisterLocalOnlyHotspotSoftApCallbackThrowsExceptionWithoutPermissionOnT() {
9961         assumeTrue(SdkLevel.isAtLeastT());
9962         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
9963                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(false);
9964         doThrow(new SecurityException())
9965                 .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
9966                         any(), anyBoolean(), any());
9967         mWifiServiceImpl.registerLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, mExtras);
9968     }
9969 
9970     /**
9971      * Verify that a call to unregisterLocalOnlyHotspotSoftApCallback throws a SecurityException
9972      * if the caller targets Android T or later and does not have nearby devices permission.
9973      */
9974     @Test(expected = SecurityException.class)
testUnregisterLocalOnlyHotspotSoftApCallbackThrowsExceptionWithoutPermissionOnT()9975     public void testUnregisterLocalOnlyHotspotSoftApCallbackThrowsExceptionWithoutPermissionOnT() {
9976         assumeTrue(SdkLevel.isAtLeastT());
9977         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
9978                 eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(false);
9979         doThrow(new SecurityException())
9980                 .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
9981                         any(), anyBoolean(), any());
9982         mWifiServiceImpl.unregisterLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, mExtras);
9983     }
9984 
9985     /**
9986      * Verify getStaConcurrencyForMultiInternetMode
9987      */
9988     @Test
testGetStaConcurrencyForMultiInternetMode()9989     public void testGetStaConcurrencyForMultiInternetMode() throws Exception {
9990         assumeTrue(SdkLevel.isAtLeastT());
9991         when(mMultiInternetManager.getStaConcurrencyForMultiInternetMode()).thenReturn(
9992                 WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP);
9993         mLooper.startAutoDispatch();
9994         final int mode = mWifiServiceImpl.getStaConcurrencyForMultiInternetMode();
9995         verify(mMultiInternetManager).getStaConcurrencyForMultiInternetMode();
9996         assertEquals(WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP, mode);
9997     }
9998 
9999     /**
10000      * Verify that a call to setStaConcurrencyForMultiInternetMode throws a SecurityException
10001      * if the caller target Android T or later and does not have network settings permission.
10002      */
10003     @Test(expected = SecurityException.class)
testSetStaConcurrencyForMultiInternetModeThrowsExceptionWithoutPermissionOnT()10004     public void testSetStaConcurrencyForMultiInternetModeThrowsExceptionWithoutPermissionOnT() {
10005         assumeTrue(SdkLevel.isAtLeastT());
10006         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
10007         when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
10008         doThrow(new SecurityException()).when(mContext)
10009                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10010                                                 eq("WifiService"));
10011         mLooper.startAutoDispatch();
10012         mWifiServiceImpl.setStaConcurrencyForMultiInternetMode(
10013                 WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP);
10014     }
10015 
10016     /**
10017      * Verify setStaConcurrencyForMultiInternetMode
10018      */
10019     @Test
testSetStaConcurrencyForMultiInternetMode()10020     public void testSetStaConcurrencyForMultiInternetMode() throws Exception {
10021         assumeTrue(SdkLevel.isAtLeastT());
10022         when(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(anyInt()))
10023                 .thenReturn(true);
10024         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10025                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10026         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
10027                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10028         mLooper.startAutoDispatch();
10029         assertTrue(mWifiServiceImpl.setStaConcurrencyForMultiInternetMode(
10030                 WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
10031         verify(mMultiInternetManager).setStaConcurrencyForMultiInternetMode(
10032                 WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP);
10033     }
10034 
10035     /**
10036      * Verify attribution is passed in correctly by WifiManager#addOrUpdateNetwork.
10037      */
10038     @Test
testAddOrUpdateNetworkAttribution_InvalidAttributions()10039     public void testAddOrUpdateNetworkAttribution_InvalidAttributions() {
10040         assumeTrue(SdkLevel.isAtLeastS());
10041         AttributionSource attributionSource = mock(AttributionSource.class);
10042         when(attributionSource.checkCallingUid()).thenReturn(true);
10043         when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
10044         mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
10045         mWifiServiceImpl = spy(mWifiServiceImpl);
10046         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(Process.SYSTEM_UID);
10047         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10048         assertThrows(SecurityException.class, () -> {
10049             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, null);
10050         });
10051 
10052         assertThrows(SecurityException.class, () -> {
10053             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, new Bundle());
10054         });
10055 
10056         assertThrows(SecurityException.class, () -> {
10057             Bundle nullEntry = new Bundle();
10058             nullEntry.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, null);
10059             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, nullEntry);
10060         });
10061 
10062         assertThrows(SecurityException.class, () -> {
10063             Bundle incorrectEntry = new Bundle();
10064             incorrectEntry.putInt(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, 10);
10065             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, incorrectEntry);
10066         });
10067 
10068         when(attributionSource.checkCallingUid()).thenReturn(false);
10069         assertThrows(SecurityException.class, () -> {
10070             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10071         });
10072         when(attributionSource.checkCallingUid()).thenReturn(true); // restore
10073 
10074         // single first attributions should not fail - even if (theoretically, doesn't happen in
10075         // practice) are not trusted. I.e. this call checks that this method isn't called.
10076         AttributionSource freshAs = mock(AttributionSource.class);
10077         Bundle freshAttribution = new Bundle();
10078         freshAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, freshAs);
10079         when(freshAs.checkCallingUid()).thenReturn(true);
10080         when(freshAs.isTrusted(any(Context.class))).thenReturn(false);
10081         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, freshAttribution);
10082         verify(freshAs, never()).isTrusted(any());
10083 
10084         AttributionSource originalCaller = mock(AttributionSource.class);
10085         when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
10086         when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
10087         when(originalCaller.isTrusted(any(Context.class))).thenReturn(false);
10088         when(attributionSource.getNext()).thenReturn(originalCaller);
10089         assertThrows(SecurityException.class, () -> {
10090             mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10091         });
10092     }
10093 
10094     /**
10095      * Verify attribution passed to WifiManager#addOrUpdateNetwork is parsed when there's no chain.
10096      */
10097     @Test
testAddOrUpdateNetworkAttribution_CorrectParsingNoChainSystemServer()10098     public void testAddOrUpdateNetworkAttribution_CorrectParsingNoChainSystemServer() {
10099         assumeTrue(SdkLevel.isAtLeastS());
10100         AttributionSource attributionSource = mock(AttributionSource.class);
10101         when(attributionSource.checkCallingUid()).thenReturn(true);
10102         when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
10103         mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
10104         mWifiServiceImpl = spy(mWifiServiceImpl);
10105         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(Process.SYSTEM_UID);
10106         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10107                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10108         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
10109                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
10110         when(attributionSource.getUid()).thenReturn(Process.SYSTEM_UID);
10111         when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
10112         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10113 
10114         mWifiThreadRunner.prepareForAutoDispatch();
10115         mLooper.startAutoDispatch();
10116         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10117         mLooper.stopAutoDispatch();
10118         verify(mWifiConfigManager).addOrUpdateNetwork(config, Process.SYSTEM_UID,
10119                 TEST_PACKAGE_NAME, false);
10120     }
10121 
10122     /**
10123      * Verify attribution passed to WifiManager#addOrUpdateNetwork is parsed when there's no chain.
10124      */
10125     @Test
testAddOrUpdateNetworkAttribution_CorrectParsingNoChainNonSystemServer()10126     public void testAddOrUpdateNetworkAttribution_CorrectParsingNoChainNonSystemServer() {
10127         assumeTrue(SdkLevel.isAtLeastS());
10128         mWifiServiceImpl = spy(mWifiServiceImpl);
10129         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(TEST_UID);
10130         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10131                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10132         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
10133                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
10134         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10135 
10136         mWifiThreadRunner.prepareForAutoDispatch();
10137         mLooper.startAutoDispatch();
10138         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, null);
10139         mLooper.stopAutoDispatch();
10140         verify(mWifiConfigManager).addOrUpdateNetwork(config, TEST_UID, TEST_PACKAGE_NAME, false);
10141     }
10142 
10143     /**
10144      * Verify attribution passed to WifiManager#addOrUpdateNetwork is parsed when there's a chain.
10145      */
10146     @Test
testAddOrUpdateNetworkAttribution_CorrectParsingWithChain()10147     public void testAddOrUpdateNetworkAttribution_CorrectParsingWithChain() {
10148         assumeTrue(SdkLevel.isAtLeastS());
10149         AttributionSource attributionSource = mock(AttributionSource.class);
10150         when(attributionSource.checkCallingUid()).thenReturn(true);
10151         when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
10152         mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
10153         mWifiServiceImpl = spy(mWifiServiceImpl);
10154         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(Process.SYSTEM_UID);
10155         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10156                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10157         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
10158                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
10159 
10160         when(attributionSource.getUid()).thenReturn(TEST_UID);
10161         when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
10162         AttributionSource originalCaller = mock(AttributionSource.class);
10163         when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
10164         when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
10165         when(originalCaller.isTrusted(any(Context.class))).thenReturn(true);
10166         when(attributionSource.getNext()).thenReturn(originalCaller);
10167 
10168         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10169 
10170         mWifiThreadRunner.prepareForAutoDispatch();
10171         mLooper.startAutoDispatch();
10172         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10173         mLooper.stopAutoDispatch();
10174         verify(mWifiConfigManager).addOrUpdateNetwork(config, OTHER_TEST_UID,
10175                 TEST_PACKAGE_NAME_OTHER, false);
10176     }
10177 
10178     /**
10179      * Verify attribution passed to WifiManager#addOrUpdateNetwork is parsed when there's a chain,
10180      * When calling from {@link WifiManager#updateNetwork(WifiConfiguration)}, the creator will be
10181      * overridden by original caller.
10182      */
10183     @Test
testAddOrUpdateNetworkAttribution_CorrectParsingWithChain_WithUpdateNetwork()10184     public void testAddOrUpdateNetworkAttribution_CorrectParsingWithChain_WithUpdateNetwork() {
10185         assumeTrue(SdkLevel.isAtLeastS());
10186         AttributionSource attributionSource = mock(AttributionSource.class);
10187         when(attributionSource.checkCallingUid()).thenReturn(true);
10188         when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
10189         mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
10190         mWifiServiceImpl = spy(mWifiServiceImpl);
10191         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(Process.SYSTEM_UID);
10192         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10193                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10194         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(true)))
10195                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
10196 
10197         when(attributionSource.getUid()).thenReturn(TEST_UID);
10198         when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
10199         AttributionSource originalCaller = mock(AttributionSource.class);
10200         when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
10201         when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
10202         when(originalCaller.isTrusted(any(Context.class))).thenReturn(true);
10203         when(attributionSource.getNext()).thenReturn(originalCaller);
10204 
10205         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10206         config.networkId = TEST_NETWORK_ID;
10207 
10208         mWifiThreadRunner.prepareForAutoDispatch();
10209         mLooper.startAutoDispatch();
10210         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10211         mLooper.stopAutoDispatch();
10212         verify(mWifiConfigManager).addOrUpdateNetwork(config, OTHER_TEST_UID,
10213                 TEST_PACKAGE_NAME_OTHER, true);
10214     }
10215 
10216     /**
10217      * Verify attribution passed to WifiManager#addOrUpdateNetwork is parsed when there's a chain.
10218      * However, if the call is not made from the system server then the attribution is ignored and
10219      * the attribution is simply to the calling app as before.
10220      */
10221     @Test
testAddOrUpdateNetworkAttribution_CorrectParsingWithChainButNotFromSystemServer()10222     public void testAddOrUpdateNetworkAttribution_CorrectParsingWithChainButNotFromSystemServer() {
10223         assumeTrue(SdkLevel.isAtLeastS());
10224         AttributionSource attributionSource = mock(AttributionSource.class);
10225         when(attributionSource.checkCallingUid()).thenReturn(true);
10226         when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
10227         mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
10228         mWifiServiceImpl = spy(mWifiServiceImpl);
10229         lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(TEST_UID);
10230         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
10231                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10232         when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
10233                 .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
10234 
10235         when(attributionSource.getUid()).thenReturn(TEST_UID);
10236         when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
10237         AttributionSource originalCaller = mock(AttributionSource.class);
10238         when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
10239         when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
10240         when(originalCaller.isTrusted(any(Context.class))).thenReturn(true);
10241         when(attributionSource.getNext()).thenReturn(originalCaller);
10242 
10243         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10244 
10245         mWifiThreadRunner.prepareForAutoDispatch();
10246         mLooper.startAutoDispatch();
10247         mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
10248         mLooper.stopAutoDispatch();
10249         verify(mWifiConfigManager).addOrUpdateNetwork(config, TEST_UID,
10250                 TEST_PACKAGE_NAME, false);
10251     }
10252 
10253     /**
10254      * Test that notifyWifiSsidPolicyChanged disconnects the current network
10255      * due to SSID allowlist restriction
10256      */
10257     @Test
testNotifyWifiSsidPolicyChangedWithAllowlistRestriction()10258     public void testNotifyWifiSsidPolicyChangedWithAllowlistRestriction()
10259             throws Exception {
10260         assumeTrue(SdkLevel.isAtLeastT());
10261 
10262         WifiInfo wifiInfo = new WifiInfo();
10263         wifiInfo.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
10264         wifiInfo.setBSSID(TEST_BSSID);
10265         wifiInfo.setNetworkId(TEST_NETWORK_ID);
10266         wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK);
10267 
10268         when(mContext.checkPermission(eq(android.Manifest.permission.MANAGE_DEVICE_ADMINS),
10269                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10270         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
10271                 Collections.singletonList(mClientModeManager));
10272         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
10273 
10274         mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
10275                 Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
10276         mLooper.dispatchAll();
10277 
10278         verify(mClientModeManager).disconnect();
10279     }
10280 
10281     /**
10282      * Test that notifyWifiSsidPolicyChanged disconnects the current network
10283      * due to SSID denylist restriction
10284      */
10285     @Test
testNotifyWifiSsidPolicyChangedWithDenylistRestriction()10286     public void testNotifyWifiSsidPolicyChangedWithDenylistRestriction()
10287             throws Exception {
10288         assumeTrue(SdkLevel.isAtLeastT());
10289 
10290         WifiInfo wifiInfo = new WifiInfo();
10291         wifiInfo.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
10292         wifiInfo.setBSSID(TEST_BSSID);
10293         wifiInfo.setNetworkId(TEST_NETWORK_ID);
10294         wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK);
10295 
10296         when(mContext.checkPermission(eq(android.Manifest.permission.MANAGE_DEVICE_ADMINS),
10297                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10298         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
10299                 Collections.singletonList(mClientModeManager));
10300         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
10301 
10302         mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
10303                 Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
10304         mLooper.dispatchAll();
10305 
10306         verify(mClientModeManager).disconnect();
10307     }
10308 
10309     /**
10310      * Test that notifyWifiSsidPolicyChanged does not disconnect the current network
10311      * due to SSID restriction for Passpoint networks
10312      */
10313     @Test
testNotifyWifiSsidPolicyChangedWithSsidRestrictionForPasspoint()10314     public void testNotifyWifiSsidPolicyChangedWithSsidRestrictionForPasspoint()
10315             throws Exception {
10316         assumeTrue(SdkLevel.isAtLeastT());
10317 
10318         WifiInfo wifiInfo = setupForGetConnectionInfo();
10319         wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2);
10320 
10321         when(mContext.checkPermission(eq(android.Manifest.permission.MANAGE_DEVICE_ADMINS),
10322                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10323         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
10324                 Collections.singletonList(mClientModeManager));
10325         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
10326 
10327         mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
10328                 Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
10329         mLooper.dispatchAll();
10330 
10331         verify(mClientModeManager, never()).disconnect();
10332     }
10333 
10334     /**
10335      * Test that notifyWifiSsidPolicyChanged does not disconnect the current network
10336      * due to SSID restriction for Osu networks
10337      */
10338     @Test
testNotifyWifiSsidPolicyChangedWithSsidRestrictionForOsu()10339     public void testNotifyWifiSsidPolicyChangedWithSsidRestrictionForOsu()
10340             throws Exception {
10341         assumeTrue(SdkLevel.isAtLeastT());
10342 
10343         WifiInfo wifiInfo = new WifiInfo();
10344         wifiInfo.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
10345         wifiInfo.setBSSID(TEST_BSSID);
10346         wifiInfo.setNetworkId(TEST_NETWORK_ID);
10347         wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3);
10348         wifiInfo.setOsuAp(true);
10349 
10350         when(mContext.checkPermission(eq(android.Manifest.permission.MANAGE_DEVICE_ADMINS),
10351                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10352         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
10353                 Collections.singletonList(mClientModeManager));
10354         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
10355 
10356         mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
10357                 Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
10358         mLooper.dispatchAll();
10359 
10360         verify(mClientModeManager, never()).disconnect();
10361     }
10362 
10363     /**
10364      * Test that notifyMinimumRequiredWifiSecurityLevelChanged disconnects the current network
10365      * due to minimum security level restriction
10366      */
10367     @Test
testNotifyMinimumRequiredWifiSecurityLevelChangedWithSecurityLevelRestriction()10368     public void testNotifyMinimumRequiredWifiSecurityLevelChangedWithSecurityLevelRestriction()
10369             throws Exception {
10370         assumeTrue(SdkLevel.isAtLeastT());
10371 
10372         WifiInfo wifiInfo = setupForGetConnectionInfo();
10373         wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK);
10374 
10375         when(mContext.checkPermission(eq(android.Manifest.permission.MANAGE_DEVICE_ADMINS),
10376                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
10377         when(mActiveModeWarden.getClientModeManagers()).thenReturn(
10378                 Collections.singletonList(mClientModeManager));
10379         when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
10380 
10381         mWifiServiceImpl.notifyMinimumRequiredWifiSecurityLevelChanged(
10382                 DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP);
10383         mLooper.dispatchAll();
10384 
10385         verify(mClientModeManager).disconnect();
10386     }
10387 
10388     @Test
testIsItPossibleToCreateInterfaceInvalidConditions()10389     public void testIsItPossibleToCreateInterfaceInvalidConditions() {
10390         assumeTrue(SdkLevel.isAtLeastT());
10391 
10392         when(mWifiPermissionsUtil.checkManageWifiInterfacesPermission(anyInt())).thenReturn(true);
10393         IInterfaceCreationInfoCallback.Stub mockCallback = mock(
10394                 IInterfaceCreationInfoCallback.Stub.class);
10395 
10396         assertThrows(IllegalArgumentException.class,
10397                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(null,
10398                         WifiManager.WIFI_INTERFACE_TYPE_AP, true, mockCallback));
10399         assertThrows(IllegalArgumentException.class,
10400                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME,
10401                         WifiManager.WIFI_INTERFACE_TYPE_AP, true, null));
10402         assertThrows(IllegalArgumentException.class,
10403                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME,
10404                         /* clearly invalid value */ 100, true, mockCallback));
10405 
10406         mWifiServiceImpl = spy(mWifiServiceImpl);
10407         when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(TEST_UID);
10408         doThrow(new SecurityException()).when(mWifiPermissionsUtil).checkPackage(TEST_UID,
10409                 TEST_PACKAGE_NAME);
10410         assertThrows(SecurityException.class,
10411                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME,
10412                         WifiManager.WIFI_INTERFACE_TYPE_AP, false, mockCallback));
10413 
10414         when(mWifiPermissionsUtil.checkManageWifiInterfacesPermission(anyInt())).thenReturn(false);
10415         assertThrows(SecurityException.class,
10416                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME,
10417                         WifiManager.WIFI_INTERFACE_TYPE_AP, false, mockCallback));
10418 
10419         when(mWifiPermissionsUtil.checkManageWifiInterfacesPermission(anyInt())).thenReturn(true);
10420         doThrow(new SecurityException()).when(mContext)
10421                 .enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
10422                         eq("WifiService"));
10423         assertThrows(SecurityException.class,
10424                 () -> mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME,
10425                         WifiManager.WIFI_INTERFACE_TYPE_AP, false, mockCallback));
10426     }
10427 
10428     @Test
testIsItPossibleToCreateInterface()10429     public void testIsItPossibleToCreateInterface() throws Exception {
10430         assumeTrue(SdkLevel.isAtLeastT());
10431 
10432         IInterfaceCreationInfoCallback.Stub mockCallback = mock(
10433                 IInterfaceCreationInfoCallback.Stub.class);
10434         final int interfaceToCreate = WifiManager.WIFI_INTERFACE_TYPE_AWARE;
10435         final int interfaceToCreateInternal = HalDeviceManager.HDM_CREATE_IFACE_NAN;
10436         mWifiServiceImpl = spy(mWifiServiceImpl);
10437         when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(TEST_UID);
10438         when(mWifiPermissionsUtil.checkManageWifiInterfacesPermission(TEST_UID)).thenReturn(true);
10439         final WorkSource ws = new WorkSource(TEST_UID, TEST_PACKAGE_NAME);
10440         final WorkSource wsOther = new WorkSource(OTHER_TEST_UID, TEST_PACKAGE_NAME_OTHER);
10441         final String[] packagesOther = {TEST_PACKAGE_NAME_OTHER};
10442 
10443         ArgumentCaptor<Boolean> boolCaptor = ArgumentCaptor.forClass(Boolean.class);
10444         ArgumentCaptor<int[]> intArrayCaptor = ArgumentCaptor.forClass(int[].class);
10445         ArgumentCaptor<String[]> stringArrayCaptor = ArgumentCaptor.forClass(String[].class);
10446 
10447         // 3 results: failure, success with no side effects, success with side effects
10448         when(mHalDeviceManager.reportImpactToCreateIface(interfaceToCreateInternal, true, ws))
10449                 .thenReturn(null)
10450                 .thenReturn(Collections.emptyList())
10451                 .thenReturn(List.of(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_P2P, wsOther)));
10452         mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME, interfaceToCreate, true,
10453                 mockCallback);
10454         mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME, interfaceToCreate, true,
10455                 mockCallback);
10456         mWifiServiceImpl.reportCreateInterfaceImpact(TEST_PACKAGE_NAME, interfaceToCreate, true,
10457                 mockCallback);
10458         mLooper.dispatchAll();
10459         verify(mHalDeviceManager, times(3)).reportImpactToCreateIface(
10460                 interfaceToCreateInternal, true, ws);
10461         verify(mockCallback, times(3)).onResults(boolCaptor.capture(), intArrayCaptor.capture(),
10462                 stringArrayCaptor.capture());
10463         verify(mPackageManager).makeUidVisible(TEST_UID, OTHER_TEST_UID);
10464 
10465         // result 0: failure
10466         assertFalse(boolCaptor.getAllValues().get(0));
10467         assertNull(intArrayCaptor.getAllValues().get(0));
10468         assertNull(stringArrayCaptor.getAllValues().get(0));
10469 
10470         // result 1: success with no side effects
10471         assertTrue(boolCaptor.getAllValues().get(1));
10472         assertEquals(0, intArrayCaptor.getAllValues().get(1).length);
10473         assertEquals(0, stringArrayCaptor.getAllValues().get(1).length);
10474 
10475         // result 2: success with no side effects
10476         assertTrue(boolCaptor.getAllValues().get(2));
10477         assertEquals(1, intArrayCaptor.getAllValues().get(2).length);
10478         assertEquals(WifiManager.WIFI_INTERFACE_TYPE_DIRECT,
10479                 intArrayCaptor.getAllValues().get(2)[0]);
10480         assertArrayEquals(packagesOther, stringArrayCaptor.getAllValues().get(2));
10481     }
10482 
10483     @Test
testTetheredSoftApTrackerWhenCountryCodeChanged()10484     public void testTetheredSoftApTrackerWhenCountryCodeChanged() throws Exception {
10485         // needed to mock this to call "handleBootCompleted"
10486         when(mWifiInjector.getPasspointProvisionerHandlerThread())
10487                 .thenReturn(mock(HandlerThread.class));
10488         mWifiServiceImpl.handleBootCompleted();
10489         mLooper.dispatchAll();
10490 
10491         registerSoftApCallbackAndVerify(mClientSoftApCallback);
10492         reset(mClientSoftApCallback);
10493         when(mWifiPermissionsUtil.checkCallersCoarseLocationPermission(
10494                 eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), anyInt(), any())).thenReturn(true);
10495         verifyRegisterDriverCountryCodeChangedListenerSucceededAndTriggerListener(
10496                 mIOnWifiDriverCountryCodeChangedListener);
10497         reset(mIOnWifiDriverCountryCodeChangedListener);
10498         ArgumentCaptor<SoftApCapability> capabilityArgumentCaptor = ArgumentCaptor.forClass(
10499                 SoftApCapability.class);
10500         // Country code update with HAL started
10501         when(mWifiNative.isHalStarted()).thenReturn(true);
10502         // Channel 9 - 2452Mhz
10503         WifiAvailableChannel channels2g = new WifiAvailableChannel(2452,
10504                 WifiAvailableChannel.OP_MODE_SAP);
10505         when(mWifiNative.isHalSupported()).thenReturn(true);
10506         when(mWifiNative.isHalStarted()).thenReturn(true);
10507         when(mWifiNative.getUsableChannels(eq(WifiScanner.WIFI_BAND_24_GHZ), anyInt(), anyInt()))
10508                 .thenReturn(new ArrayList<>(Arrays.asList(channels2g)));
10509         mWifiServiceImpl.mCountryCodeTracker.onCountryCodeChangePending(TEST_COUNTRY_CODE);
10510         mLooper.dispatchAll();
10511         mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
10512         mLooper.dispatchAll();
10513         verify(mIOnWifiDriverCountryCodeChangedListener)
10514                 .onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
10515         verify(mClientSoftApCallback).onCapabilityChanged(capabilityArgumentCaptor.capture());
10516         assertEquals(1, capabilityArgumentCaptor.getValue()
10517                 .getSupportedChannelList(SoftApConfiguration.BAND_2GHZ).length);
10518         assertEquals(9, capabilityArgumentCaptor.getValue()
10519                 .getSupportedChannelList(SoftApConfiguration.BAND_2GHZ)[0]);
10520         reset(mClientSoftApCallback);
10521         // Country code update with HAL not started
10522         when(mWifiNative.isHalStarted()).thenReturn(false);
10523         mWifiServiceImpl.mCountryCodeTracker.onCountryCodeChangePending(TEST_NEW_COUNTRY_CODE);
10524         mLooper.dispatchAll();
10525         verify(mIOnWifiDriverCountryCodeChangedListener, never())
10526                 .onDriverCountryCodeChanged(TEST_NEW_COUNTRY_CODE);
10527         verify(mClientSoftApCallback)
10528                 .onCapabilityChanged(capabilityArgumentCaptor.capture());
10529         // The supported channels in soft AP capability got invalidated.
10530         assertEquals(0, capabilityArgumentCaptor.getValue()
10531                 .getSupportedChannelList(SoftApConfiguration.BAND_2GHZ).length);
10532     }
10533 
10534     /**
10535      * Verify that change network connection state is not allowed for App target below Q SDK from
10536      * guest user
10537      */
10538     @Test
testNotAllowedToChangeWifiOpsTargetBelowQSdkFromGuestUser()10539     public void testNotAllowedToChangeWifiOpsTargetBelowQSdkFromGuestUser() throws Exception {
10540         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
10541                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
10542         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
10543                 eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
10544         when(mWifiPermissionsUtil.isGuestUser()).thenReturn(true);
10545 
10546         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
10547         verify(mWifiMetrics, never()).incrementNumWifiToggles(anyBoolean(), anyBoolean());
10548 
10549         assertFalse(mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME));
10550         assertFalse(mWifiServiceImpl.reconnect(TEST_PACKAGE_NAME));
10551         assertFalse(mWifiServiceImpl.reassociate(TEST_PACKAGE_NAME));
10552 
10553         assertTrue(mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE_NAME, TEST_FEATURE_ID,
10554                 false).getList().isEmpty());
10555         mLooper.dispatchAll();
10556         verify(mWifiConfigManager, never()).getConfiguredNetworks();
10557 
10558         assertFalse(mWifiServiceImpl.removeNetwork(0, TEST_PACKAGE_NAME));
10559         mLooper.dispatchAll();
10560         verify(mWifiConfigManager, never()).removeNetwork(anyInt(), anyInt(), anyString());
10561 
10562         assertFalse(mWifiServiceImpl.enableNetwork(0, false, TEST_PACKAGE_NAME));
10563         mLooper.dispatchAll();
10564         verify(mWifiConfigManager, never()).enableNetwork(anyInt(), anyBoolean(), anyInt(),
10565                 anyString());
10566         verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
10567 
10568         assertFalse(mWifiServiceImpl.disableNetwork(0, TEST_PACKAGE_NAME));
10569         mLooper.dispatchAll();
10570         verify(mWifiConfigManager, never()).disableNetwork(anyInt(), anyInt(), anyString());
10571 
10572         PasspointConfiguration passpointConfig = new PasspointConfiguration();
10573         HomeSp homeSp = new HomeSp();
10574         homeSp.setFqdn("test.com");
10575         passpointConfig.setHomeSp(homeSp);
10576         assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(passpointConfig,
10577                 TEST_PACKAGE_NAME));
10578         mLooper.dispatchAll();
10579         verify(mPasspointManager, never()).addOrUpdateProvider(any(), anyInt(), anyString(),
10580                 anyBoolean(), anyBoolean());
10581 
10582         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
10583         assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME,
10584                 mAttribution));
10585     }
10586 }
10587