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.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY;
20 import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
21 import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
22 import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
23 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
24 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
25 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
26 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
27 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
28 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
29 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
30 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
31 import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
32 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
33 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
34 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
35 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
36 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
37 import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G;
38 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
39 
40 import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
41 import static com.android.server.wifi.WifiController.CMD_SET_AP;
42 import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
43 
44 import static org.junit.Assert.assertEquals;
45 import static org.junit.Assert.assertFalse;
46 import static org.junit.Assert.assertNotNull;
47 import static org.junit.Assert.assertNull;
48 import static org.junit.Assert.assertTrue;
49 import static org.junit.Assert.fail;
50 import static org.mockito.Matchers.any;
51 import static org.mockito.Matchers.anyString;
52 import static org.mockito.Matchers.eq;
53 import static org.mockito.Mockito.anyBoolean;
54 import static org.mockito.Mockito.anyInt;
55 import static org.mockito.Mockito.anyLong;
56 import static org.mockito.Mockito.anyObject;
57 import static org.mockito.Mockito.argThat;
58 import static org.mockito.Mockito.atLeastOnce;
59 import static org.mockito.Mockito.doNothing;
60 import static org.mockito.Mockito.doReturn;
61 import static org.mockito.Mockito.doThrow;
62 import static org.mockito.Mockito.inOrder;
63 import static org.mockito.Mockito.isNull;
64 import static org.mockito.Mockito.mock;
65 import static org.mockito.Mockito.never;
66 import static org.mockito.Mockito.reset;
67 import static org.mockito.Mockito.spy;
68 import static org.mockito.Mockito.times;
69 import static org.mockito.Mockito.verify;
70 import static org.mockito.Mockito.verifyNoMoreInteractions;
71 import static org.mockito.Mockito.verifyZeroInteractions;
72 import static org.mockito.Mockito.when;
73 
74 import android.Manifest;
75 import android.app.ActivityManager;
76 import android.app.AppOpsManager;
77 import android.app.admin.DeviceAdminInfo;
78 import android.app.admin.DevicePolicyManagerInternal;
79 import android.content.BroadcastReceiver;
80 import android.content.ContentResolver;
81 import android.content.Context;
82 import android.content.Intent;
83 import android.content.IntentFilter;
84 import android.content.pm.ApplicationInfo;
85 import android.content.pm.PackageManager;
86 import android.content.pm.ParceledListSlice;
87 import android.content.res.Resources;
88 import android.net.Uri;
89 import android.net.wifi.IDppCallback;
90 import android.net.wifi.INetworkRequestMatchCallback;
91 import android.net.wifi.IOnWifiUsabilityStatsListener;
92 import android.net.wifi.ISoftApCallback;
93 import android.net.wifi.ITrafficStateCallback;
94 import android.net.wifi.ScanResult;
95 import android.net.wifi.WifiConfiguration;
96 import android.net.wifi.WifiConfiguration.KeyMgmt;
97 import android.net.wifi.WifiEnterpriseConfig;
98 import android.net.wifi.WifiInfo;
99 import android.net.wifi.WifiManager;
100 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
101 import android.net.wifi.WifiManager.SoftApCallback;
102 import android.net.wifi.WifiSsid;
103 import android.net.wifi.hotspot2.IProvisioningCallback;
104 import android.net.wifi.hotspot2.OsuProvider;
105 import android.net.wifi.hotspot2.PasspointConfiguration;
106 import android.net.wifi.hotspot2.pps.HomeSp;
107 import android.os.Binder;
108 import android.os.Build;
109 import android.os.Handler;
110 import android.os.HandlerThread;
111 import android.os.IBinder;
112 import android.os.IPowerManager;
113 import android.os.Looper;
114 import android.os.Message;
115 import android.os.Messenger;
116 import android.os.PowerManager;
117 import android.os.Process;
118 import android.os.RemoteException;
119 import android.os.UserManager;
120 import android.os.test.TestLooper;
121 import android.telephony.TelephonyManager;
122 
123 import androidx.test.filters.SmallTest;
124 
125 import com.android.internal.os.PowerProfile;
126 import com.android.internal.telephony.TelephonyIntents;
127 import com.android.internal.util.AsyncChannel;
128 import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
129 import com.android.server.wifi.hotspot2.PasspointManager;
130 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil;
131 import com.android.server.wifi.util.WifiAsyncChannel;
132 import com.android.server.wifi.util.WifiPermissionsUtil;
133 import com.android.server.wifi.util.WifiPermissionsWrapper;
134 
135 import org.junit.Before;
136 import org.junit.Test;
137 import org.mockito.ArgumentCaptor;
138 import org.mockito.ArgumentMatcher;
139 import org.mockito.InOrder;
140 import org.mockito.Mock;
141 import org.mockito.MockitoAnnotations;
142 import org.mockito.Spy;
143 
144 import java.io.FileDescriptor;
145 import java.io.PrintWriter;
146 import java.io.StringWriter;
147 import java.util.ArrayList;
148 import java.util.Arrays;
149 import java.util.List;
150 
151 /**
152  * Unit tests for {@link WifiServiceImpl}.
153  *
154  * Note: this is intended to build up over time and will not immediately cover the entire file.
155  */
156 @SmallTest
157 public class WifiServiceImplTest {
158 
159     private static final String TAG = "WifiServiceImplTest";
160     private static final String SCAN_PACKAGE_NAME = "scanPackage";
161     private static final int DEFAULT_VERBOSE_LOGGING = 0;
162     private static final String ANDROID_SYSTEM_PACKAGE = "android";
163     private static final String TEST_PACKAGE_NAME = "TestPackage";
164     private static final String SYSUI_PACKAGE_NAME = "com.android.systemui";
165     private static final int TEST_PID = 6789;
166     private static final int TEST_PID2 = 9876;
167     private static final int TEST_UID = 1200000;
168     private static final int OTHER_TEST_UID = 1300000;
169     private static final int TEST_USER_HANDLE = 13;
170     private static final int TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER = 17;
171     private static final int TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER = 234;
172     private static final int TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER = 2;
173     private static final String WIFI_IFACE_NAME = "wlan0";
174     private static final String WIFI_IFACE_NAME2 = "wlan1";
175     private static final String TEST_COUNTRY_CODE = "US";
176     private static final String TEST_FACTORY_MAC = "10:22:34:56:78:92";
177     private static final List<WifiConfiguration> TEST_WIFI_CONFIGURATION_LIST = Arrays.asList(
178             WifiConfigurationTestUtil.generateWifiConfig(
179                     0, 1000000, "\"red\"", true, true, null, null),
180             WifiConfigurationTestUtil.generateWifiConfig(
181                     1, 1000001, "\"green\"", true, false, "example.com", "Green"),
182             WifiConfigurationTestUtil.generateWifiConfig(
183                     2, 1200000, "\"blue\"", false, true, null, null),
184             WifiConfigurationTestUtil.generateWifiConfig(
185                     3, 1100000, "\"cyan\"", true, true, null, null),
186             WifiConfigurationTestUtil.generateWifiConfig(
187                     4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow"),
188             WifiConfigurationTestUtil.generateWifiConfig(
189                     5, 1100002, "\"magenta\"", false, false, null, null));
190 
191     private AsyncChannel mAsyncChannel;
192     private WifiServiceImpl mWifiServiceImpl;
193     private TestLooper mLooper;
194     private PowerManager mPowerManager;
195     private Handler mHandler;
196     private Handler mHandlerSpyForCmiRunWithScissors;
197     private Messenger mAppMessenger;
198     private int mPid;
199     private int mPid2 = Process.myPid();
200     private OsuProvider mOsuProvider;
201     private SoftApCallback mStateMachineSoftApCallback;
202     private ApplicationInfo mApplicationInfo;
203     private static final String DPP_URI = "DPP:some_dpp_uri";
204 
205     final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
206             ArgumentCaptor.forClass(BroadcastReceiver.class);
207     final ArgumentCaptor<IntentFilter> mIntentFilterCaptor =
208             ArgumentCaptor.forClass(IntentFilter.class);
209 
210     final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class);
211     final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor =
212             ArgumentCaptor.forClass(SoftApModeConfiguration.class);
213     final ArgumentCaptor<Handler> mHandlerCaptor = ArgumentCaptor.forClass(Handler.class);
214 
215     @Mock Context mContext;
216     @Mock WifiInjector mWifiInjector;
217     @Mock WifiCountryCode mWifiCountryCode;
218     @Mock Clock mClock;
219     @Mock WifiController mWifiController;
220     @Mock WifiTrafficPoller mWifiTrafficPoller;
221     @Mock ClientModeImpl mClientModeImpl;
222     @Mock ActiveModeWarden mActiveModeWarden;
223     @Mock HandlerThread mHandlerThread;
224     @Mock Resources mResources;
225     @Mock FrameworkFacade mFrameworkFacade;
226     @Mock WifiLockManager mLockManager;
227     @Mock WifiMulticastLockManager mWifiMulticastLockManager;
228     @Mock WifiLastResortWatchdog mWifiLastResortWatchdog;
229     @Mock WifiBackupRestore mWifiBackupRestore;
230     @Mock WifiMetrics mWifiMetrics;
231     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
232     @Mock WifiPermissionsWrapper mWifiPermissionsWrapper;
233     @Mock WifiSettingsStore mSettingsStore;
234     @Mock ContentResolver mContentResolver;
235     @Mock PackageManager mPackageManager;
236     @Mock UserManager mUserManager;
237     @Mock WifiApConfigStore mWifiApConfigStore;
238     @Mock WifiConfiguration mApConfig;
239     @Mock ActivityManager mActivityManager;
240     @Mock AppOpsManager mAppOpsManager;
241     @Mock IBinder mAppBinder;
242     @Mock IBinder mAnotherAppBinder;
243     @Mock LocalOnlyHotspotRequestInfo mRequestInfo;
244     @Mock LocalOnlyHotspotRequestInfo mRequestInfo2;
245     @Mock IProvisioningCallback mProvisioningCallback;
246     @Mock ISoftApCallback mClientSoftApCallback;
247     @Mock ISoftApCallback mAnotherSoftApCallback;
248     @Mock PowerProfile mPowerProfile;
249     @Mock WifiTrafficPoller mWifiTrafficPolller;
250     @Mock ScanRequestProxy mScanRequestProxy;
251     @Mock ITrafficStateCallback mTrafficStateCallback;
252     @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback;
253     @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
254     @Mock DevicePolicyManagerInternal mDevicePolicyManagerInternal;
255     @Mock TelephonyManager mTelephonyManager;
256     @Mock IOnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
257     @Mock WifiConfigManager mWifiConfigManager;
258     @Mock WifiScoreReport mWifiScoreReport;
259     @Mock WifiScoreCard mWifiScoreCard;
260     @Mock PasspointManager mPasspointManager;
261     @Mock IDppCallback mDppCallback;
262 
263     @Spy FakeWifiLog mLog;
264 
265     private class WifiAsyncChannelTester {
266         private static final String TAG = "WifiAsyncChannelTester";
267         public static final int CHANNEL_STATE_FAILURE = -1;
268         public static final int CHANNEL_STATE_DISCONNECTED = 0;
269         public static final int CHANNEL_STATE_HALF_CONNECTED = 1;
270         public static final int CHANNEL_STATE_FULLY_CONNECTED = 2;
271 
272         private int mState = CHANNEL_STATE_DISCONNECTED;
273         private WifiAsyncChannel mChannel;
274         private WifiLog mAsyncTestLog;
275 
WifiAsyncChannelTester(WifiInjector wifiInjector)276         WifiAsyncChannelTester(WifiInjector wifiInjector) {
277             mAsyncTestLog = wifiInjector.makeLog(TAG);
278         }
279 
getChannelState()280         public int getChannelState() {
281             return mState;
282         }
283 
connect(final Looper looper, final Messenger messenger, final Handler incomingMessageHandler)284         public void connect(final Looper looper, final Messenger messenger,
285                 final Handler incomingMessageHandler) {
286             assertEquals("AsyncChannel must be in disconnected state",
287                     CHANNEL_STATE_DISCONNECTED, mState);
288             mChannel = new WifiAsyncChannel(TAG);
289             mChannel.setWifiLog(mLog);
290             Handler handler = new Handler(mLooper.getLooper()) {
291                 @Override
292                 public void handleMessage(Message msg) {
293                     switch (msg.what) {
294                         case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
295                             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
296                                 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
297                                 mState = CHANNEL_STATE_HALF_CONNECTED;
298                             } else {
299                                 mState = CHANNEL_STATE_FAILURE;
300                             }
301                             break;
302                         case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
303                             mState = CHANNEL_STATE_FULLY_CONNECTED;
304                             break;
305                         case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
306                             mState = CHANNEL_STATE_DISCONNECTED;
307                             break;
308                         default:
309                             incomingMessageHandler.handleMessage(msg);
310                             break;
311                     }
312                 }
313             };
314             mChannel.connect(null, handler, messenger);
315         }
316 
sendMessageSynchronously(Message request)317         private Message sendMessageSynchronously(Message request) {
318             return mChannel.sendMessageSynchronously(request);
319         }
320 
sendMessage(Message request)321         private void sendMessage(Message request) {
322             mChannel.sendMessage(request);
323         }
324     }
325 
setUp()326     @Before public void setUp() throws Exception {
327         MockitoAnnotations.initMocks(this);
328         mLooper = new TestLooper();
329         mHandler = spy(new Handler(mLooper.getLooper()));
330         mAppMessenger = new Messenger(mHandler);
331         mAsyncChannel = spy(new AsyncChannel());
332         mApplicationInfo = new ApplicationInfo();
333         mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
334 
335         WifiInjector.sWifiInjector = mWifiInjector;
336         when(mRequestInfo.getPid()).thenReturn(mPid);
337         when(mRequestInfo2.getPid()).thenReturn(mPid2);
338         when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
339         when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode);
340         when(mWifiInjector.getWifiController()).thenReturn(mWifiController);
341         when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
342         when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
343         when(mClientModeImpl.syncInitialize(any())).thenReturn(true);
344         when(mClientModeImpl.getHandler()).thenReturn(new Handler());
345         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
346         when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread);
347         when(mWifiInjector.getPowerProfile()).thenReturn(mPowerProfile);
348         when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
349         when(mContext.getResources()).thenReturn(mResources);
350         when(mContext.getContentResolver()).thenReturn(mContentResolver);
351         when(mContext.getPackageManager()).thenReturn(mPackageManager);
352         when(mPackageManager.getApplicationInfo(any(), anyInt())).thenReturn(mApplicationInfo);
353         when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
354         doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(),
355                 anyBoolean(), any());
356         when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
357         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
358         IPowerManager powerManagerService = mock(IPowerManager.class);
359         mPowerManager = new PowerManager(mContext, powerManagerService, new Handler());
360         when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE);
361         when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
362         WifiAsyncChannel wifiAsyncChannel = new WifiAsyncChannel("WifiServiceImplTest");
363         wifiAsyncChannel.setWifiLog(mLog);
364         when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(wifiAsyncChannel);
365         when(mWifiPermissionsWrapper.getDevicePolicyManagerInternal())
366                 .thenReturn(mDevicePolicyManagerInternal);
367         when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
368         when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager);
369         when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager);
370         when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog);
371         when(mWifiInjector.getWifiBackupRestore()).thenReturn(mWifiBackupRestore);
372         when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
373         when(mWifiInjector.getWifiTrafficPoller()).thenReturn(mWifiTrafficPoller);
374         when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil);
375         when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
376         when(mWifiInjector.getWifiSettingsStore()).thenReturn(mSettingsStore);
377         when(mWifiInjector.getClock()).thenReturn(mClock);
378         when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy);
379         when(mWifiInjector.getWifiNetworkSuggestionsManager())
380                 .thenReturn(mWifiNetworkSuggestionsManager);
381         when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager);
382         when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager);
383         when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager);
384         when(mClientModeImpl.getWifiScoreReport()).thenReturn(mWifiScoreReport);
385         when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard);
386         when(mClientModeImpl.syncStartSubscriptionProvisioning(anyInt(),
387                 any(OsuProvider.class), any(IProvisioningCallback.class), any())).thenReturn(true);
388         when(mPackageManager.hasSystemFeature(
389                 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
390         // Create an OSU provider that can be provisioned via an open OSU AP
391         mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
392         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
393         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
394                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
395         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
396                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
397         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_STACK),
398                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
399         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
400                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
401         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true);
402 
403         ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
404                 ArgumentCaptor.forClass(SoftApCallback.class);
405         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
406         verify(mActiveModeWarden).registerSoftApCallback(softApCallbackCaptor.capture());
407         mStateMachineSoftApCallback = softApCallbackCaptor.getValue();
408         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
409         mDppCallback = new IDppCallback() {
410             @Override
411             public void onSuccessConfigReceived(int newNetworkId) throws RemoteException {
412 
413             }
414 
415             @Override
416             public void onSuccess(int status) throws RemoteException {
417 
418             }
419 
420             @Override
421             public void onFailure(int status) throws RemoteException {
422 
423             }
424 
425             @Override
426             public void onProgress(int status) throws RemoteException {
427 
428             }
429 
430             @Override
431             public IBinder asBinder() {
432                 return null;
433             }
434         };
435     }
436 
verifyAsyncChannelHalfConnected()437     private WifiAsyncChannelTester verifyAsyncChannelHalfConnected() throws RemoteException {
438         WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector);
439         Handler handler = mock(Handler.class);
440         TestLooper looper = new TestLooper();
441         channelTester.connect(looper.getLooper(),
442                 mWifiServiceImpl.getWifiServiceMessenger(TEST_PACKAGE_NAME), handler);
443         mLooper.dispatchAll();
444         assertEquals("AsyncChannel must be half connected",
445                 WifiAsyncChannelTester.CHANNEL_STATE_HALF_CONNECTED,
446                 channelTester.getChannelState());
447         return channelTester;
448     }
449 
450     /**
451      * Verifies that any operations on WifiServiceImpl without setting up the ClientModeImpl
452      * channel would fail.
453      */
454     @Test
testRemoveNetworkUnknown()455     public void testRemoveNetworkUnknown() {
456         assertFalse(mWifiServiceImpl.removeNetwork(-1, TEST_PACKAGE_NAME));
457         verify(mClientModeImpl, never()).syncRemoveNetwork(any(), anyInt());
458     }
459 
460     /**
461      * Tests whether we're able to set up an async channel connection with WifiServiceImpl.
462      * This is the path used by some WifiManager public API calls.
463      */
464     @Test
testAsyncChannelHalfConnected()465     public void testAsyncChannelHalfConnected() throws RemoteException {
466         verifyAsyncChannelHalfConnected();
467     }
468 
469     /**
470      * Ensure WifiMetrics.dump() is the only dump called when 'dumpsys wifi WifiMetricsProto' is
471      * called. This is required to support simple metrics collection via dumpsys
472      */
473     @Test
testWifiMetricsDump()474     public void testWifiMetricsDump() {
475         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()),
476                 new String[]{mWifiMetrics.PROTO_DUMP_ARG});
477         verify(mWifiMetrics)
478                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
479         verify(mClientModeImpl, never())
480                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
481     }
482 
483     /**
484      * Ensure WifiServiceImpl.dump() doesn't throw an NPE when executed with null args
485      */
486     @Test
testDumpNullArgs()487     public void testDumpNullArgs() {
488         setupClientModeImplHandlerForRunWithScissors();
489 
490         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
491     }
492 
493     /**
494      * Ensure that WifiServiceImpl.dump() calls
495      * {@link ClientModeImpl#updateLinkLayerStatsRssiAndScoreReport()}, then calls
496      * mWifiInjector.getClientModeImplHandler().runWithScissors() at least once before calling
497      * {@link WifiScoreReport#dump(FileDescriptor, PrintWriter, String[])}.
498      *
499      * runWithScissors() needs to be called at least once so that we know that the async call
500      * {@link ClientModeImpl#updateLinkLayerStatsRssiAndScoreReport()} has completed, since
501      * runWithScissors() blocks the current thread until the call completes, which includes all
502      * previous calls posted to that thread.
503      *
504      * This ensures that WifiScoreReport will always get updated RSSI and link layer stats before
505      * dumping during a bug report, no matter if the screen is on or not.
506      */
507     @Test
testWifiScoreReportDump()508     public void testWifiScoreReportDump() {
509         setupClientModeImplHandlerForRunWithScissors();
510 
511         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
512 
513         InOrder inOrder = inOrder(mClientModeImpl, mHandlerSpyForCmiRunWithScissors,
514                 mWifiScoreReport);
515 
516         inOrder.verify(mClientModeImpl).updateLinkLayerStatsRssiAndScoreReport();
517         inOrder.verify(mHandlerSpyForCmiRunWithScissors, atLeastOnce())
518                 .runWithScissors(any(), anyLong());
519         inOrder.verify(mWifiScoreReport).dump(any(), any(), any());
520     }
521 
522     /**
523      * Verify that metrics is incremented correctly for Privileged Apps.
524      */
525     @Test
testSetWifiEnabledMetricsPrivilegedApp()526     public void testSetWifiEnabledMetricsPrivilegedApp() throws Exception {
527         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
528                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
529         when(mSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
530         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
531 
532         InOrder inorder = inOrder(mWifiMetrics);
533         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
534         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
535         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(true));
536         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(true), eq(false));
537     }
538 
539     /**
540      * Verify that metrics is incremented correctly for normal Apps targeting pre-Q.
541      */
542     @Test
testSetWifiEnabledMetricsNormalAppBelowQSDK()543     public void testSetWifiEnabledMetricsNormalAppBelowQSDK() throws Exception {
544         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
545                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
546         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
547                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
548         when(mSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
549         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
550 
551         InOrder inorder = inOrder(mWifiMetrics);
552         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
553         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
554         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(false), eq(true));
555         inorder.verify(mWifiMetrics).incrementNumWifiToggles(eq(false), eq(false));
556     }
557 
558     /**
559      * Verify that metrics is not incremented by apps targeting Q SDK.
560      */
561     @Test
testSetWifiEnabledMetricsNormalAppTargetingQSDKNoIncrement()562     public void testSetWifiEnabledMetricsNormalAppTargetingQSDKNoIncrement() throws Exception {
563         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
564                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
565         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
566                 eq(Build.VERSION_CODES.Q))).thenReturn(false);
567         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
568         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
569 
570         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
571         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
572         verify(mWifiMetrics, never()).incrementNumWifiToggles(anyBoolean(), anyBoolean());
573     }
574 
575     /**
576      * Verify that wifi can be enabled by a caller with NETWORK_SETTINGS permission.
577      */
578     @Test
testSetWifiEnabledSuccessWithNetworkSettingsPermission()579     public void testSetWifiEnabledSuccessWithNetworkSettingsPermission() throws Exception {
580         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
581                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
582         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
583         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
584         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
585         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
586     }
587 
588     /**
589      * Verify that wifi can be enabled by a caller with NETWORK_MANAGED_PROVISIONING permission.
590      */
591     @Test
testSetWifiEnabledSuccessWithNetworkManagedProvisioningPermission()592     public void testSetWifiEnabledSuccessWithNetworkManagedProvisioningPermission()
593             throws Exception {
594         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
595                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
596         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
597         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
598         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
599         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
600     }
601 
602     /**
603      * Verify that wifi can be enabled by the apps targeting pre-Q SDK.
604      */
605     @Test
testSetWifiEnabledSuccessForAppsTargetingBelowQSDK()606     public void testSetWifiEnabledSuccessForAppsTargetingBelowQSDK() throws Exception {
607         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
608                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
609         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
610                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
611 
612         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
613         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
614         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
615 
616         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
617     }
618 
619     /**
620      * Verify that wifi cannot be enabled by the apps targeting Q SDK.
621      */
622     @Test
testSetWifiEnabledFailureForAppsTargetingQSDK()623     public void testSetWifiEnabledFailureForAppsTargetingQSDK() throws Exception {
624         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
625                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
626         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
627                 eq(Build.VERSION_CODES.Q))).thenReturn(false);
628 
629         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
630         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
631         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
632 
633         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
634     }
635 
636     /**
637      * Verify a SecurityException is thrown if OPSTR_CHANGE_WIFI_STATE is disabled for the app.
638      */
639     @Test
testSetWifiEnableAppOpsRejected()640     public void testSetWifiEnableAppOpsRejected() throws Exception {
641         doThrow(new SecurityException()).when(mAppOpsManager)
642                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
643         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
644                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
645         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
646         try {
647             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
648             fail();
649         } catch (SecurityException e) {
650 
651         }
652         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
653     }
654 
655     /**
656      * Verify a SecurityException is thrown if OP_CHANGE_WIFI_STATE is set to MODE_IGNORED
657      * for the app.
658      */
659     @Test // No exception expected, but the operation should not be done
testSetWifiEnableAppOpsIgnored()660     public void testSetWifiEnableAppOpsIgnored() throws Exception {
661         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
662                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
663         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
664                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
665         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
666 
667         mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
668         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
669     }
670 
671     /**
672      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
673      * are in airplane mode.
674      */
675     @Test
testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode()676     public void testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode() throws Exception {
677         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
678         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
679         when(mContext.checkPermission(
680                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
681                 .thenReturn(PackageManager.PERMISSION_GRANTED);
682 
683         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
684         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
685     }
686 
687     /**
688      * Verify that a caller without the NETWORK_SETTINGS permission can't enable wifi
689      * if we are in airplane mode.
690      */
691     @Test
testSetWifiEnabledFromAppFailsWhenInAirplaneMode()692     public void testSetWifiEnabledFromAppFailsWhenInAirplaneMode() throws Exception {
693         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
694                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
695         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
696                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
697         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
698         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
699         when(mContext.checkPermission(
700                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
701                 .thenReturn(PackageManager.PERMISSION_DENIED);
702 
703         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
704         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
705     }
706 
707     /**
708      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
709      * are in softap mode.
710      */
711     @Test
testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled()712     public void testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled() throws Exception {
713         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
714         mWifiServiceImpl.checkAndStartWifi();
715 
716         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
717                 (IntentFilter) argThat(new IntentFilterMatcher()));
718 
719         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
720                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
721                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
722 
723         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
724         when(mContext.checkPermission(
725                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
726                 .thenReturn(PackageManager.PERMISSION_GRANTED);
727         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
728         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
729         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
730     }
731 
732     /**
733      * Verify that a call from an app cannot enable wifi if we are in softap mode.
734      */
735     @Test
testSetWifiEnabledFromAppFailsWhenApEnabled()736     public void testSetWifiEnabledFromAppFailsWhenApEnabled() throws Exception {
737         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
738                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
739         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
740                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
741         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
742         mWifiServiceImpl.checkAndStartWifi();
743 
744         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
745                 (IntentFilter) argThat(new IntentFilterMatcher()));
746 
747         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
748                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
749                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
750 
751         when(mContext.checkPermission(
752                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
753                 .thenReturn(PackageManager.PERMISSION_DENIED);
754         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
755         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
756         verify(mSettingsStore, never()).handleWifiToggled(anyBoolean());
757         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
758     }
759 
760 
761     /**
762      * Verify that the CMD_TOGGLE_WIFI message won't be sent if wifi is already on.
763      */
764     @Test
testSetWifiEnabledNoToggle()765     public void testSetWifiEnabledNoToggle() throws Exception {
766         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(false);
767         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
768                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
769         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
770         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
771     }
772 
773     /**
774      * Verify a SecurityException is thrown if a caller does not have the CHANGE_WIFI_STATE
775      * permission to toggle wifi.
776      */
777     @Test
testSetWifiEnableWithoutChangeWifiStatePermission()778     public void testSetWifiEnableWithoutChangeWifiStatePermission() throws Exception {
779         doThrow(new SecurityException()).when(mContext)
780                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
781                                                 eq("WifiService"));
782         try {
783             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
784             fail();
785         } catch (SecurityException e) {
786         }
787     }
788 
789     /**
790      * Verify that wifi can be disabled by a caller with NETWORK_SETTINGS permission.
791      */
792     @Test
testSetWifiDisabledSuccessWithNetworkSettingsPermission()793     public void testSetWifiDisabledSuccessWithNetworkSettingsPermission() throws Exception {
794         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
795                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
796         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
797         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
798         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
799     }
800 
801     /**
802      * Verify that wifi can be disabled by a caller with NETWORK_MANAGED_PROVISIONING permission.
803      */
804     @Test
testSetWifiDisabledSuccessWithNetworkManagedProvisioningPermission()805     public void testSetWifiDisabledSuccessWithNetworkManagedProvisioningPermission()
806             throws Exception {
807         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
808                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
809         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
810         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
811         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
812     }
813 
814     /**
815      * Verify that wifi can be disabled by the apps targeting pre-Q SDK.
816      */
817     @Test
testSetWifiDisabledSuccessForAppsTargetingBelowQSDK()818     public void testSetWifiDisabledSuccessForAppsTargetingBelowQSDK() throws Exception {
819         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
820                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
821         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
822                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
823 
824         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
825         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
826         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
827 
828         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
829     }
830 
831     /**
832      * Verify that wifi cannot be disabled by the apps targeting Q SDK.
833      */
834     @Test
testSetWifiDisabledFailureForAppsTargetingQSDK()835     public void testSetWifiDisabledFailureForAppsTargetingQSDK() throws Exception {
836         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
837                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
838         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
839                 eq(Build.VERSION_CODES.Q))).thenReturn(false);
840 
841         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
842         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
843         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
844 
845         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
846     }
847 
848     /**
849      * Verify that CMD_TOGGLE_WIFI message won't be sent if wifi is already off.
850      */
851     @Test
testSetWifiDisabledNoToggle()852     public void testSetWifiDisabledNoToggle() throws Exception {
853         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
854                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
855         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false);
856         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
857         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
858     }
859 
860     /**
861      * Verify a SecurityException is thrown if a caller does not have the CHANGE_WIFI_STATE
862      * permission to toggle wifi.
863      */
864     @Test
testSetWifiDisabledWithoutChangeWifiStatePermission()865     public void testSetWifiDisabledWithoutChangeWifiStatePermission() throws Exception {
866         doThrow(new SecurityException()).when(mContext)
867                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
868                         eq("WifiService"));
869         try {
870             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false);
871             fail();
872         } catch (SecurityException e) { }
873     }
874 
875     /**
876      * Ensure unpermitted callers cannot write the SoftApConfiguration.
877      *
878      * @throws SecurityException
879      */
880     @Test
testSetWifiApConfigurationNotSavedWithoutPermission()881     public void testSetWifiApConfigurationNotSavedWithoutPermission() {
882         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
883         WifiConfiguration apConfig = new WifiConfiguration();
884         try {
885             mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME);
886             fail("Expected SecurityException");
887         } catch (SecurityException e) { }
888     }
889 
890     /**
891      * Ensure softap config is written when the caller has the correct permission.
892      */
893     @Test
testSetWifiApConfigurationSuccess()894     public void testSetWifiApConfigurationSuccess() {
895         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
896         WifiConfiguration apConfig = createValidSoftApConfiguration();
897 
898         assertTrue(mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME));
899         mLooper.dispatchAll();
900         verifyCheckChangePermission(TEST_PACKAGE_NAME);
901         verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
902     }
903 
904     /**
905      * Ensure that a null config does not overwrite the saved ap config.
906      */
907     @Test
testSetWifiApConfigurationNullConfigNotSaved()908     public void testSetWifiApConfigurationNullConfigNotSaved() {
909         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
910         assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME));
911         verify(mWifiApConfigStore, never()).setApConfiguration(isNull(WifiConfiguration.class));
912     }
913 
914     /**
915      * Ensure that an invalid config does not overwrite the saved ap config.
916      */
917     @Test
testSetWifiApConfigurationWithInvalidConfigNotSaved()918     public void testSetWifiApConfigurationWithInvalidConfigNotSaved() {
919         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
920         assertFalse(mWifiServiceImpl.setWifiApConfiguration(new WifiConfiguration(),
921                                                             TEST_PACKAGE_NAME));
922         verify(mWifiApConfigStore, never()).setApConfiguration(any());
923     }
924 
925     /**
926      * Ensure unpermitted callers are not able to retrieve the softap config.
927      *
928      * @throws SecurityException
929      */
930     @Test
testGetWifiApConfigurationNotReturnedWithoutPermission()931     public void testGetWifiApConfigurationNotReturnedWithoutPermission() {
932         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
933         try {
934             mWifiServiceImpl.getWifiApConfiguration();
935             fail("Expected a SecurityException");
936         } catch (SecurityException e) {
937         }
938     }
939 
940     /**
941      * Ensure permitted callers are able to retrieve the softap config.
942      */
943     @Test
testGetWifiApConfigurationSuccess()944     public void testGetWifiApConfigurationSuccess() {
945         setupClientModeImplHandlerForRunWithScissors();
946 
947         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
948         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
949 
950         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
951         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
952 
953         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
954         WifiConfiguration apConfig = new WifiConfiguration();
955         when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig);
956         assertEquals(apConfig, mWifiServiceImpl.getWifiApConfiguration());
957     }
958 
959     /**
960      * Ensure we return the proper variable for the softap state after getting an AP state change
961      * broadcast.
962      */
963     @Test
testGetWifiApEnabled()964     public void testGetWifiApEnabled() {
965         setupClientModeImplHandlerForRunWithScissors();
966 
967         // set up WifiServiceImpl with a live thread for testing
968         HandlerThread serviceHandlerThread = createAndStartHandlerThreadForRunWithScissors();
969         when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(serviceHandlerThread);
970         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
971         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
972 
973         // ap should be disabled when wifi hasn't been started
974         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
975 
976         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
977         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
978         mWifiServiceImpl.checkAndStartWifi();
979         mLooper.dispatchAll();
980 
981         // ap should be disabled initially
982         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
983 
984         // send an ap state change to verify WifiServiceImpl is updated
985         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
986                 (IntentFilter) argThat(new IntentFilterMatcher()));
987 
988         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
989                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
990                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
991         mLooper.dispatchAll();
992 
993         assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState());
994     }
995 
996     /**
997      * Ensure we do not allow unpermitted callers to get the wifi ap state.
998      */
999     @Test
testGetWifiApEnabledPermissionDenied()1000     public void testGetWifiApEnabledPermissionDenied() {
1001         // we should not be able to get the state
1002         doThrow(new SecurityException()).when(mContext)
1003                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.ACCESS_WIFI_STATE),
1004                                                 eq("WifiService"));
1005 
1006         try {
1007             mWifiServiceImpl.getWifiApEnabledState();
1008             fail("expected SecurityException");
1009         } catch (SecurityException expected) { }
1010     }
1011 
1012     /**
1013      * Make sure we do not start wifi if System services have to be restarted to decrypt the device.
1014      */
1015     @Test
testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot()1016     public void testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot() {
1017         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
1018         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1019         mWifiServiceImpl.checkAndStartWifi();
1020         verify(mWifiController, never()).start();
1021     }
1022 
1023     /**
1024      * Make sure we do start WifiController (wifi disabled) if the device is already decrypted.
1025      */
1026     @Test
testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled()1027     public void testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled() {
1028         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
1029         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1030         mWifiServiceImpl.checkAndStartWifi();
1031         verify(mWifiController).start();
1032         verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED);
1033     }
1034 
1035     /**
1036      * Make sure we do start WifiController (wifi enabled) if the device is already decrypted.
1037      */
1038     @Test
testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled()1039     public void testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled() {
1040         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
1041         when(mSettingsStore.handleWifiToggled(true)).thenReturn(true);
1042         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
1043         when(mClientModeImpl.syncGetWifiState()).thenReturn(WIFI_STATE_DISABLED);
1044         when(mContext.getPackageName()).thenReturn(ANDROID_SYSTEM_PACKAGE);
1045         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1046                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1047         mWifiServiceImpl.checkAndStartWifi();
1048         verify(mWifiController).start();
1049         verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED);
1050     }
1051 
1052     /**
1053      * Verify caller with proper permission can call startSoftAp.
1054      */
1055     @Test
testStartSoftApWithPermissionsAndNullConfig()1056     public void testStartSoftApWithPermissionsAndNullConfig() {
1057         boolean result = mWifiServiceImpl.startSoftAp(null);
1058         assertTrue(result);
1059         verify(mWifiController)
1060                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
1061         assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
1062     }
1063 
1064     /**
1065      * Verify caller with proper permissions but an invalid config does not start softap.
1066      */
1067     @Test
testStartSoftApWithPermissionsAndInvalidConfig()1068     public void testStartSoftApWithPermissionsAndInvalidConfig() {
1069         boolean result = mWifiServiceImpl.startSoftAp(mApConfig);
1070         assertFalse(result);
1071         verifyZeroInteractions(mWifiController);
1072     }
1073 
1074     /**
1075      * Verify caller with proper permission and valid config does start softap.
1076      */
1077     @Test
testStartSoftApWithPermissionsAndValidConfig()1078     public void testStartSoftApWithPermissionsAndValidConfig() {
1079         WifiConfiguration config = createValidSoftApConfiguration();
1080         boolean result = mWifiServiceImpl.startSoftAp(config);
1081         assertTrue(result);
1082         verify(mWifiController)
1083                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
1084         assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
1085     }
1086 
1087     /**
1088      * Verify a SecurityException is thrown when a caller without the correct permission attempts to
1089      * start softap.
1090      */
1091     @Test(expected = SecurityException.class)
testStartSoftApWithoutPermissionThrowsException()1092     public void testStartSoftApWithoutPermissionThrowsException() throws Exception {
1093         doThrow(new SecurityException()).when(mContext)
1094                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
1095                                                 eq("WifiService"));
1096         mWifiServiceImpl.startSoftAp(null);
1097     }
1098 
1099     /**
1100      * Verify caller with proper permission can call stopSoftAp.
1101      */
1102     @Test
testStopSoftApWithPermissions()1103     public void testStopSoftApWithPermissions() {
1104         boolean result = mWifiServiceImpl.stopSoftAp();
1105         assertTrue(result);
1106         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
1107                 eq(WifiManager.IFACE_IP_MODE_TETHERED));
1108     }
1109 
1110     /**
1111      * Verify SecurityException is thrown when a caller without the correct permission attempts to
1112      * stop softap.
1113      */
1114     @Test(expected = SecurityException.class)
testStopSoftApWithoutPermissionThrowsException()1115     public void testStopSoftApWithoutPermissionThrowsException() throws Exception {
1116         doThrow(new SecurityException()).when(mContext)
1117                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
1118                                                 eq("WifiService"));
1119         mWifiServiceImpl.stopSoftAp();
1120     }
1121 
1122     /**
1123      * Ensure that we handle app ops check failure when handling scan request.
1124      */
1125     @Test
testStartScanFailureAppOpsIgnored()1126     public void testStartScanFailureAppOpsIgnored() {
1127         setupClientModeImplHandlerForRunWithScissors();
1128         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
1129                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME);
1130         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
1131         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
1132     }
1133 
1134     /**
1135      * Ensure that we handle scan access permission check failure when handling scan request.
1136      */
1137     @Test
testStartScanFailureInCanAccessScanResultsPermission()1138     public void testStartScanFailureInCanAccessScanResultsPermission() {
1139         setupClientModeImplHandlerForRunWithScissors();
1140         doThrow(new SecurityException()).when(mWifiPermissionsUtil)
1141                 .enforceCanAccessScanResults(SCAN_PACKAGE_NAME, Process.myUid());
1142         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
1143         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
1144     }
1145 
1146     /**
1147      * Ensure that we handle scan request failure when posting the runnable to handler fails.
1148      */
1149     @Test
testStartScanFailureInRunWithScissors()1150     public void testStartScanFailureInRunWithScissors() {
1151         setupClientModeImplHandlerForRunWithScissors();
1152         doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
1153                 .runWithScissors(any(), anyLong());
1154         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
1155         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
1156     }
1157 
1158     /**
1159      * Ensure that we handle scan request failure from ScanRequestProxy fails.
1160      */
1161     @Test
testStartScanFailureFromScanRequestProxy()1162     public void testStartScanFailureFromScanRequestProxy() {
1163         setupClientModeImplHandlerForRunWithScissors();
1164         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false);
1165         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
1166         verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
1167     }
1168 
1169     static final String TEST_SSID = "Sid's Place";
1170     static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
1171     static final String TEST_BSSID = "01:02:03:04:05:06";
1172     static final String TEST_PACKAGE = "package";
1173     static final int TEST_NETWORK_ID = 567;
1174 
setupForGetConnectionInfo()1175     private void setupForGetConnectionInfo() {
1176         WifiInfo wifiInfo = new WifiInfo();
1177         wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
1178         wifiInfo.setBSSID(TEST_BSSID);
1179         wifiInfo.setNetworkId(TEST_NETWORK_ID);
1180         when(mClientModeImpl.syncRequestConnectionInfo()).thenReturn(wifiInfo);
1181     }
1182 
1183     /**
1184      * Test that connected SSID and BSSID are not exposed to an app that does not have the
1185      * appropriate permissions.
1186      */
1187     @Test
testConnectedIdsAreHiddenFromAppWithoutPermission()1188     public void testConnectedIdsAreHiddenFromAppWithoutPermission() throws Exception {
1189         setupForGetConnectionInfo();
1190 
1191         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
1192                 anyString(), anyInt());
1193 
1194         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
1195 
1196         assertEquals(WifiSsid.NONE, connectionInfo.getSSID());
1197         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
1198         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, connectionInfo.getNetworkId());
1199     }
1200 
1201     /**
1202      * Test that connected SSID and BSSID are not exposed to an app that does not have the
1203      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
1204      */
1205     @Test
testConnectedIdsAreHiddenOnSecurityException()1206     public void testConnectedIdsAreHiddenOnSecurityException() throws Exception {
1207         setupForGetConnectionInfo();
1208 
1209         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
1210                 anyString(), anyInt());
1211 
1212         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
1213 
1214         assertEquals(WifiSsid.NONE, connectionInfo.getSSID());
1215         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
1216         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, connectionInfo.getNetworkId());
1217     }
1218 
1219     /**
1220      * Test that connected SSID and BSSID are exposed to an app that does have the
1221      * appropriate permissions.
1222      */
1223     @Test
testConnectedIdsAreVisibleFromPermittedApp()1224     public void testConnectedIdsAreVisibleFromPermittedApp() throws Exception {
1225         setupForGetConnectionInfo();
1226 
1227         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
1228 
1229         assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID());
1230         assertEquals(TEST_BSSID, connectionInfo.getBSSID());
1231         assertEquals(TEST_NETWORK_ID, connectionInfo.getNetworkId());
1232     }
1233 
1234     /**
1235      * Test that configured network list are exposed empty list to an app that does not have the
1236      * appropriate permissions.
1237      */
1238     @Test
testConfiguredNetworkListAreEmptyFromAppWithoutPermission()1239     public void testConfiguredNetworkListAreEmptyFromAppWithoutPermission() throws Exception {
1240         when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
1241                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1242 
1243         // no permission = target SDK=Q && not a carrier app
1244         when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(anyString())).thenReturn(
1245                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
1246 
1247         ParceledListSlice<WifiConfiguration> configs =
1248                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE);
1249 
1250         assertEquals(0, configs.getList().size());
1251     }
1252 
1253     /**
1254      * Test that configured network list are exposed empty list to an app that does not have the
1255      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
1256      */
1257     @Test
testConfiguredNetworkListAreEmptyOnSecurityException()1258     public void testConfiguredNetworkListAreEmptyOnSecurityException() throws Exception {
1259         when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
1260                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1261 
1262         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
1263                 anyString(), anyInt());
1264 
1265         ParceledListSlice<WifiConfiguration> configs =
1266                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE);
1267 
1268         assertEquals(0, configs.getList().size());
1269 
1270     }
1271 
1272     /**
1273      * Test that configured network list are exposed to an app that does have the
1274      * appropriate permissions.
1275      */
1276     @Test
testConfiguredNetworkListAreVisibleFromPermittedApp()1277     public void testConfiguredNetworkListAreVisibleFromPermittedApp() throws Exception {
1278         when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
1279                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1280 
1281         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1282                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
1283 
1284         mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
1285 
1286         ParceledListSlice<WifiConfiguration> configs =
1287                 mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE);
1288 
1289         verify(mClientModeImpl).syncGetConfiguredNetworks(anyInt(), any(), eq(Process.WIFI_UID));
1290         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
1291                 TEST_WIFI_CONFIGURATION_LIST, configs.getList());
1292     }
1293 
1294 
1295     /**
1296      * Test that privileged network list are exposed null to an app that does not have the
1297      * appropriate permissions.
1298      */
1299     @Test
testPrivilegedConfiguredNetworkListAreEmptyFromAppWithoutPermission()1300     public void testPrivilegedConfiguredNetworkListAreEmptyFromAppWithoutPermission()
1301             throws Exception {
1302         when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
1303                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1304 
1305         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
1306                 anyString(), anyInt());
1307 
1308         ParceledListSlice<WifiConfiguration> configs =
1309                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
1310 
1311         assertEquals(null, configs);
1312     }
1313 
1314     /**
1315      * Test that privileged network list are exposed null to an app that does not have the
1316      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
1317      */
1318     @Test
testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException()1319     public void testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException() throws Exception {
1320         when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
1321                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1322 
1323         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
1324                 anyString(), anyInt());
1325 
1326         ParceledListSlice<WifiConfiguration> configs =
1327                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
1328 
1329         assertEquals(null, configs);
1330 
1331     }
1332 
1333     /**
1334      * Test that privileged network list are exposed to an app that does have the
1335      * appropriate permissions (simulated by not throwing an exception for READ_WIFI_CREDENTIAL).
1336      */
1337     @Test
testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp()1338     public void testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp() throws Exception {
1339         when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
1340                 .thenReturn(TEST_WIFI_CONFIGURATION_LIST);
1341 
1342         mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
1343 
1344         ParceledListSlice<WifiConfiguration> configs =
1345                 mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
1346 
1347         WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
1348                 TEST_WIFI_CONFIGURATION_LIST, configs.getList());
1349     }
1350 
1351     /**
1352      * Test fetching of scan results.
1353      */
1354     @Test
testGetScanResults()1355     public void testGetScanResults() {
1356         setupClientModeImplHandlerForRunWithScissors();
1357 
1358         ScanResult[] scanResults =
1359                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
1360                         .getResults();
1361         List<ScanResult> scanResultList =
1362                 new ArrayList<>(Arrays.asList(scanResults));
1363         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
1364 
1365         String packageName = "test.com";
1366         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
1367         verify(mScanRequestProxy).getScanResults();
1368 
1369         ScanTestUtil.assertScanResultsEquals(scanResults,
1370                 retrievedScanResultList.toArray(new ScanResult[retrievedScanResultList.size()]));
1371     }
1372 
1373     /**
1374      * Ensure that we handle scan results failure when posting the runnable to handler fails.
1375      */
1376     @Test
testGetScanResultsFailureInRunWithScissors()1377     public void testGetScanResultsFailureInRunWithScissors() {
1378         setupClientModeImplHandlerForRunWithScissors();
1379         doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
1380                 .runWithScissors(any(), anyLong());
1381 
1382         ScanResult[] scanResults =
1383                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
1384                         .getResults();
1385         List<ScanResult> scanResultList =
1386                 new ArrayList<>(Arrays.asList(scanResults));
1387         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
1388 
1389         String packageName = "test.com";
1390         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
1391         verify(mScanRequestProxy, never()).getScanResults();
1392 
1393         assertTrue(retrievedScanResultList.isEmpty());
1394     }
1395 
registerLOHSRequestFull()1396     private void registerLOHSRequestFull() {
1397         // allow test to proceed without a permission check failure
1398         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
1399         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
1400         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
1401                 .thenReturn(false);
1402         int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
1403                 TEST_PACKAGE_NAME);
1404         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
1405         verifyCheckChangePermission(TEST_PACKAGE_NAME);
1406     }
1407 
1408     /**
1409      * Verify that the call to startLocalOnlyHotspot returns REQUEST_REGISTERED when successfully
1410      * called.
1411      */
1412     @Test
testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered()1413     public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() {
1414         registerLOHSRequestFull();
1415     }
1416 
1417     /**
1418      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
1419      * have the CHANGE_WIFI_STATE permission.
1420      */
1421     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission()1422     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() {
1423         doThrow(new SecurityException()).when(mContext)
1424                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
1425                                                 eq("WifiService"));
1426         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1427     }
1428 
1429     /**
1430      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
1431      * have Location permission.
1432      */
1433     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission()1434     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission() {
1435         doThrow(new SecurityException())
1436                 .when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME),
1437                                                                       anyInt());
1438         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1439     }
1440 
1441     /**
1442      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if Location mode is
1443      * disabled.
1444      */
1445     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled()1446     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() {
1447         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
1448         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1449     }
1450 
1451     /**
1452      * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request.
1453      */
1454     @Test
testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp()1455     public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
1456         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
1457 
1458         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
1459         int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
1460                 TEST_PACKAGE_NAME);
1461         assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
1462     }
1463 
1464     /**
1465      * Only start LocalOnlyHotspot if we are not tethering.
1466      */
1467     @Test
testTetheringDoesNotStartWhenAlreadyTetheringActive()1468     public void testTetheringDoesNotStartWhenAlreadyTetheringActive() throws Exception {
1469         setupClientModeImplHandlerForPost();
1470 
1471         WifiConfiguration config = createValidSoftApConfiguration();
1472         assertTrue(mWifiServiceImpl.startSoftAp(config));
1473         verify(mWifiController)
1474                 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
1475         assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
1476 
1477         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
1478         mLooper.dispatchAll();
1479 
1480         // Start another session without a stop, that should fail.
1481         assertFalse(mWifiServiceImpl.startSoftAp(createValidSoftApConfiguration()));
1482 
1483         verifyNoMoreInteractions(mWifiController);
1484     }
1485 
1486     /**
1487      * Only start LocalOnlyHotspot if we are not tethering.
1488      */
1489     @Test
testHotspotDoesNotStartWhenAlreadyTethering()1490     public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
1491         setupClientModeImplHandlerForPost();
1492 
1493         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
1494         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
1495         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
1496         mLooper.dispatchAll();
1497         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
1498                 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1499         assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode);
1500     }
1501 
1502     /**
1503      * Only start LocalOnlyHotspot if admin setting does not disallow tethering.
1504      */
1505     @Test
testHotspotDoesNotStartWhenTetheringDisallowed()1506     public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
1507         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
1508         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
1509         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
1510                 .thenReturn(true);
1511         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
1512                 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1513         assertEquals(ERROR_TETHERING_DISALLOWED, returnCode);
1514     }
1515 
1516     /**
1517      * Verify that callers can only have one registered LOHS request.
1518      */
1519     @Test(expected = IllegalStateException.class)
testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered()1520     public void testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered() {
1521         registerLOHSRequestFull();
1522 
1523         // now do the second request that will fail
1524         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
1525     }
1526 
1527     /**
1528      * Verify that the call to stopLocalOnlyHotspot does not do anything when there aren't any
1529      * registered callers.
1530      */
1531     @Test
testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests()1532     public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() {
1533         // allow test to proceed without a permission check failure
1534         mWifiServiceImpl.stopLocalOnlyHotspot();
1535         // there is nothing registered, so this shouldn't do anything
1536         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
1537     }
1538 
1539     /**
1540      * Verify that the call to stopLocalOnlyHotspot does not do anything when one caller unregisters
1541      * but there is still an active request
1542      */
1543     @Test
testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest()1544     public void testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest() {
1545         // register a request that will remain after the stopLOHS call
1546         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
1547 
1548         registerLOHSRequestFull();
1549 
1550         // Since we are calling with the same pid, the second register call will be removed
1551         mWifiServiceImpl.stopLocalOnlyHotspot();
1552         // there is still a valid registered request - do not tear down LOHS
1553         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
1554     }
1555 
1556     /**
1557      * Verify that the call to stopLocalOnlyHotspot sends a message to WifiController to stop
1558      * the softAp when there is one registered caller when that caller is removed.
1559      */
1560     @Test
testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest()1561     public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() {
1562         registerLOHSRequestFull();
1563         verify(mWifiController)
1564                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
1565 
1566         // No permission check required for change_wifi_state.
1567         verify(mContext, never()).enforceCallingOrSelfPermission(
1568                 eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString());
1569 
1570         mWifiServiceImpl.stopLocalOnlyHotspot();
1571         // there is was only one request registered, we should tear down softap
1572         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
1573                 eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
1574     }
1575 
1576     /**
1577      * Verify that by default startLocalOnlyHotspot starts access point at 2 GHz.
1578      */
1579     @Test
testStartLocalOnlyHotspotAt2Ghz()1580     public void testStartLocalOnlyHotspotAt2Ghz() {
1581         registerLOHSRequestFull();
1582         verifyLohsBand(WifiConfiguration.AP_BAND_2GHZ);
1583     }
1584 
1585     /**
1586      * Verify that startLocalOnlyHotspot will start access point at 5 GHz if properly configured.
1587      */
1588     @Test
testStartLocalOnlyHotspotAt5Ghz()1589     public void testStartLocalOnlyHotspotAt5Ghz() {
1590         when(mResources.getBoolean(
1591                 eq(com.android.internal.R.bool.config_wifi_local_only_hotspot_5ghz)))
1592                 .thenReturn(true);
1593         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(true);
1594         when(mClientModeImpl.syncGetSupportedFeatures(any(AsyncChannel.class)))
1595                 .thenReturn((long) WIFI_FEATURE_INFRA_5G);
1596 
1597         verify(mAsyncChannel).connect(any(), mHandlerCaptor.capture(), any(Handler.class));
1598         final Handler handler = mHandlerCaptor.getValue();
1599         handler.handleMessage(handler.obtainMessage(
1600                 AsyncChannel.CMD_CHANNEL_HALF_CONNECTED, AsyncChannel.STATUS_SUCCESSFUL, 0));
1601 
1602         registerLOHSRequestFull();
1603         verifyLohsBand(WifiConfiguration.AP_BAND_5GHZ);
1604     }
1605 
verifyLohsBand(int expectedBand)1606     private void verifyLohsBand(int expectedBand) {
1607         verify(mWifiController)
1608                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
1609         final WifiConfiguration configuration = mSoftApModeConfigCaptor.getValue().mConfig;
1610         assertNotNull(configuration);
1611         assertEquals(expectedBand, configuration.apBand);
1612     }
1613 
1614     /**
1615          * Verify that WifiServiceImpl does not send the stop ap message if there were no
1616          * pending LOHS requests upon a binder death callback.
1617          */
1618     @Test
testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests()1619     public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() {
1620         LocalOnlyRequestorCallback binderDeathCallback =
1621                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
1622 
1623         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
1624         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0),
1625                 eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
1626     }
1627 
1628     /**
1629      * Verify that WifiServiceImpl does not send the stop ap message if there are remaining
1630      * registered LOHS requests upon a binder death callback.  Additionally verify that softap mode
1631      * will be stopped if that remaining request is removed (to verify the binder death properly
1632      * cleared the requestor that died).
1633      */
1634     @Test
testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests()1635     public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests() {
1636         LocalOnlyRequestorCallback binderDeathCallback =
1637                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
1638 
1639         // registering a request directly from the test will not trigger a message to start
1640         // softap mode
1641         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
1642 
1643         registerLOHSRequestFull();
1644 
1645         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
1646         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
1647 
1648         reset(mWifiController);
1649 
1650         // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder
1651         // death requestor was removed
1652         mWifiServiceImpl.stopLocalOnlyHotspot();
1653         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
1654                 eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
1655     }
1656 
1657     /**
1658      * Verify that a call to registerSoftApCallback throws a SecurityException if the caller does
1659      * not have NETWORK_SETTINGS permission.
1660      */
1661     @Test
registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions()1662     public void registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
1663         doThrow(new SecurityException()).when(mContext)
1664                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1665                                                 eq("WifiService"));
1666         try {
1667             final int callbackIdentifier = 1;
1668             mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
1669                     callbackIdentifier);
1670             fail("expected SecurityException");
1671         } catch (SecurityException expected) {
1672         }
1673     }
1674 
1675     /**
1676      * Verify that a call to registerSoftApCallback throws an IllegalArgumentException if the
1677      * parameters are not provided.
1678      */
1679     @Test
registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()1680     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
1681         try {
1682             final int callbackIdentifier = 1;
1683             mWifiServiceImpl.registerSoftApCallback(mAppBinder, null, callbackIdentifier);
1684             fail("expected IllegalArgumentException");
1685         } catch (IllegalArgumentException expected) {
1686         }
1687     }
1688 
1689     /**
1690      * Verify that a call to unregisterSoftApCallback throws a SecurityException if the caller does
1691      * not have NETWORK_SETTINGS permission.
1692      */
1693     @Test
unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions()1694     public void unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
1695         doThrow(new SecurityException()).when(mContext)
1696                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
1697                                                 eq("WifiService"));
1698         try {
1699             final int callbackIdentifier = 1;
1700             mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
1701             fail("expected SecurityException");
1702         } catch (SecurityException expected) {
1703         }
1704     }
1705 
1706     /**
1707      * Verifies that we handle softap callback registration failure if we encounter an exception
1708      * while linking to death.
1709      */
1710     @Test
registerSoftApCallbackFailureOnLinkToDeath()1711     public void registerSoftApCallbackFailureOnLinkToDeath() throws Exception {
1712         setupClientModeImplHandlerForPost();
1713 
1714         doThrow(new RemoteException())
1715                 .when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
1716         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1);
1717         mLooper.dispatchAll();
1718         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
1719         verify(mClientSoftApCallback, never()).onNumClientsChanged(0);
1720     }
1721 
1722 
1723     /**
1724      * Registers a soft AP callback, then verifies that the current soft AP state and num clients
1725      * are sent to caller immediately after callback is registered.
1726      */
registerSoftApCallbackAndVerify(ISoftApCallback callback, int callbackIdentifier)1727     private void registerSoftApCallbackAndVerify(ISoftApCallback callback, int callbackIdentifier)
1728             throws Exception {
1729         registerSoftApCallbackAndVerify(mAppBinder, callback, callbackIdentifier);
1730     }
1731 
1732     /**
1733      * Registers a soft AP callback, then verifies that the current soft AP state and num clients
1734      * are sent to caller immediately after callback is registered.
1735      */
registerSoftApCallbackAndVerify(IBinder binder, ISoftApCallback callback, int callbackIdentifier)1736     private void registerSoftApCallbackAndVerify(IBinder binder, ISoftApCallback callback,
1737                                                  int callbackIdentifier) throws Exception {
1738         mWifiServiceImpl.registerSoftApCallback(binder, callback, callbackIdentifier);
1739         mLooper.dispatchAll();
1740         verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
1741         verify(callback).onNumClientsChanged(0);
1742     }
1743 
1744     /**
1745      * Verify that registering twice with same callbackIdentifier will replace the first callback.
1746      */
1747     @Test
replacesOldCallbackWithNewCallbackWhenRegisteringTwice()1748     public void replacesOldCallbackWithNewCallbackWhenRegisteringTwice() throws Exception {
1749         setupClientModeImplHandlerForPost();
1750 
1751         final int callbackIdentifier = 1;
1752         registerSoftApCallbackAndVerify(mAppBinder, mClientSoftApCallback, callbackIdentifier);
1753         registerSoftApCallbackAndVerify(
1754                 mAnotherAppBinder, mAnotherSoftApCallback, callbackIdentifier);
1755 
1756         verify(mAppBinder).linkToDeath(any(), anyInt());
1757         verify(mAppBinder).unlinkToDeath(any(), anyInt());
1758         verify(mAnotherAppBinder).linkToDeath(any(), anyInt());
1759         verify(mAnotherAppBinder, never()).unlinkToDeath(any(), anyInt());
1760 
1761         final int testNumClients = 4;
1762         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1763         mLooper.dispatchAll();
1764         // Verify only the second callback is being called
1765         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
1766         verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
1767     }
1768 
1769     /**
1770      * Verify that unregisterSoftApCallback removes callback from registered callbacks list
1771      */
1772     @Test
unregisterSoftApCallbackRemovesCallback()1773     public void unregisterSoftApCallbackRemovesCallback() throws Exception {
1774         setupClientModeImplHandlerForPost();
1775 
1776         final int callbackIdentifier = 1;
1777         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1778 
1779         mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
1780         mLooper.dispatchAll();
1781 
1782         final int testNumClients = 4;
1783         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1784         mLooper.dispatchAll();
1785         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
1786     }
1787 
1788     /**
1789      * Verify that unregisterSoftApCallback is no-op if callbackIdentifier not registered.
1790      */
1791     @Test
unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching()1792     public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching()
1793             throws Exception {
1794         setupClientModeImplHandlerForPost();
1795 
1796         final int callbackIdentifier = 1;
1797         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1798 
1799         final int differentCallbackIdentifier = 2;
1800         mWifiServiceImpl.unregisterSoftApCallback(differentCallbackIdentifier);
1801         mLooper.dispatchAll();
1802 
1803         final int testNumClients = 4;
1804         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1805         mLooper.dispatchAll();
1806         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
1807     }
1808 
1809     /**
1810      * Registers two callbacks, remove one then verify the right callback is being called on events.
1811      */
1812     @Test
correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne()1813     public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception {
1814         setupClientModeImplHandlerForPost();
1815 
1816         final int callbackIdentifier = 1;
1817         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
1818                 callbackIdentifier);
1819 
1820         // Change state from default before registering the second callback
1821         final int testNumClients = 4;
1822         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1823         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1824 
1825         // Register another callback and verify the new state is returned in the immediate callback
1826         final int anotherUid = 2;
1827         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mAnotherSoftApCallback, anotherUid);
1828         mLooper.dispatchAll();
1829         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1830         verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
1831 
1832         // unregister the fisrt callback
1833         mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
1834         mLooper.dispatchAll();
1835 
1836         // Update soft AP state and verify the remaining callback receives the event
1837         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
1838                 SAP_START_FAILURE_NO_CHANNEL);
1839         mLooper.dispatchAll();
1840         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
1841                 SAP_START_FAILURE_NO_CHANNEL);
1842         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
1843                 SAP_START_FAILURE_NO_CHANNEL);
1844     }
1845 
1846     /**
1847      * Verify that wifi service registers for callers BinderDeath event
1848      */
1849     @Test
registersForBinderDeathOnRegisterSoftApCallback()1850     public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception {
1851         setupClientModeImplHandlerForPost();
1852 
1853         final int callbackIdentifier = 1;
1854         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1855         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
1856     }
1857 
1858     /**
1859      * Verify that we un-register the soft AP callback on receiving BinderDied event.
1860      */
1861     @Test
unregistersSoftApCallbackOnBinderDied()1862     public void unregistersSoftApCallbackOnBinderDied() throws Exception {
1863         setupClientModeImplHandlerForPost();
1864 
1865         ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
1866                 ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
1867         final int callbackIdentifier = 1;
1868         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1869         verify(mAppBinder).linkToDeath(drCaptor.capture(), anyInt());
1870 
1871         drCaptor.getValue().binderDied();
1872         mLooper.dispatchAll();
1873         verify(mAppBinder).unlinkToDeath(drCaptor.getValue(), 0);
1874 
1875         // Verify callback is removed from the list as well
1876         final int testNumClients = 4;
1877         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1878         mLooper.dispatchAll();
1879         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
1880     }
1881 
1882     /**
1883      * Verify that soft AP callback is called on NumClientsChanged event
1884      */
1885     @Test
callsRegisteredCallbacksOnNumClientsChangedEvent()1886     public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception {
1887         setupClientModeImplHandlerForPost();
1888 
1889         final int callbackIdentifier = 1;
1890         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1891 
1892         final int testNumClients = 4;
1893         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1894         mLooper.dispatchAll();
1895         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
1896     }
1897 
1898     /**
1899      * Verify that soft AP callback is called on SoftApStateChanged event
1900      */
1901     @Test
callsRegisteredCallbacksOnSoftApStateChangedEvent()1902     public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception {
1903         setupClientModeImplHandlerForPost();
1904 
1905         final int callbackIdentifier = 1;
1906         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
1907 
1908         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1909         mLooper.dispatchAll();
1910         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1911     }
1912 
1913     /**
1914      * Verify that mSoftApState and mSoftApNumClients in WifiServiceImpl are being updated on soft
1915      * Ap events, even when no callbacks are registered.
1916      */
1917     @Test
updatesSoftApStateAndNumClientsOnSoftApEvents()1918     public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception {
1919         setupClientModeImplHandlerForPost();
1920 
1921         final int testNumClients = 4;
1922         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1923         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
1924 
1925         // Register callback after num clients and soft AP are changed.
1926         final int callbackIdentifier = 1;
1927         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
1928                 callbackIdentifier);
1929         mLooper.dispatchAll();
1930         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
1931         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
1932     }
1933 
1934     private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
1935         @Override
matches(IntentFilter filter)1936         public boolean matches(IntentFilter filter) {
1937             return filter.hasAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
1938         }
1939     }
1940 
1941     /**
1942      * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
1943      * broadcast is received.
1944      */
1945     @Test
testRegisteredCallbacksTriggeredOnSoftApFailureGeneric()1946     public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception {
1947         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
1948         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1949         mWifiServiceImpl.checkAndStartWifi();
1950 
1951         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
1952                 (IntentFilter) argThat(new IntentFilterMatcher()));
1953 
1954         registerLOHSRequestFull();
1955 
1956         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
1957                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
1958                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
1959         mLooper.dispatchAll();
1960         verify(mHandler).handleMessage(mMessageCaptor.capture());
1961         Message message = mMessageCaptor.getValue();
1962         assertEquals(HOTSPOT_FAILED, message.what);
1963         assertEquals(ERROR_GENERIC, message.arg1);
1964     }
1965 
1966     /**
1967      * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
1968      * broadcast is received with the SAP_START_FAILURE_NO_CHANNEL error.
1969      */
1970     @Test
testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel()1971     public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception {
1972         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
1973         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
1974         mWifiServiceImpl.checkAndStartWifi();
1975 
1976         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
1977                 (IntentFilter) argThat(new IntentFilterMatcher()));
1978 
1979         registerLOHSRequestFull();
1980 
1981         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
1982                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL,
1983                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
1984 
1985         mLooper.dispatchAll();
1986         verify(mHandler).handleMessage(mMessageCaptor.capture());
1987         Message message = mMessageCaptor.getValue();
1988         assertEquals(HOTSPOT_FAILED, message.what);
1989         assertEquals(ERROR_NO_CHANNEL, message.arg1);
1990     }
1991 
1992     /**
1993      * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
1994      * broadcast is received with WIFI_AP_STATE_DISABLING and LOHS was active.
1995      */
1996     @Test
testRegisteredCallbacksTriggeredOnSoftApDisabling()1997     public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception {
1998         setupClientModeImplHandlerForPost();
1999 
2000         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2001         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2002         mWifiServiceImpl.checkAndStartWifi();
2003 
2004         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2005                 (IntentFilter) argThat(new IntentFilterMatcher()));
2006 
2007         registerLOHSRequestFull();
2008 
2009         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2010         mLooper.dispatchAll();
2011         verify(mHandler).handleMessage(mMessageCaptor.capture());
2012         Message message = mMessageCaptor.getValue();
2013         assertEquals(HOTSPOT_STARTED, message.what);
2014         reset(mHandler);
2015 
2016         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2017                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
2018                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2019 
2020         mLooper.dispatchAll();
2021         verify(mHandler).handleMessage(mMessageCaptor.capture());
2022         message = mMessageCaptor.getValue();
2023         assertEquals(HOTSPOT_STOPPED, message.what);
2024     }
2025 
2026 
2027     /**
2028      * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
2029      * broadcast is received with WIFI_AP_STATE_DISABLED and LOHS was enabled.
2030      */
2031     @Test
testRegisteredCallbacksTriggeredOnSoftApDisabled()2032     public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception {
2033         setupClientModeImplHandlerForPost();
2034 
2035         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2036         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2037         mWifiServiceImpl.checkAndStartWifi();
2038 
2039         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2040                 (IntentFilter) argThat(new IntentFilterMatcher()));
2041 
2042         registerLOHSRequestFull();
2043 
2044         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2045         mLooper.dispatchAll();
2046         verify(mHandler).handleMessage(mMessageCaptor.capture());
2047         Message message = mMessageCaptor.getValue();
2048         assertEquals(HOTSPOT_STARTED, message.what);
2049         reset(mHandler);
2050 
2051         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2052                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
2053                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2054 
2055         mLooper.dispatchAll();
2056         verify(mHandler).handleMessage(mMessageCaptor.capture());
2057         message = mMessageCaptor.getValue();
2058         assertEquals(HOTSPOT_STOPPED, message.what);
2059     }
2060 
2061     /**
2062      * Verify that no callbacks are called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
2063      * broadcast is received and the softap started.
2064      */
2065     @Test
testRegisteredCallbacksNotTriggeredOnSoftApStart()2066     public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception {
2067         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2068         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2069         mWifiServiceImpl.checkAndStartWifi();
2070 
2071         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2072                 (IntentFilter) argThat(new IntentFilterMatcher()));
2073 
2074         registerLOHSRequestFull();
2075 
2076         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2077                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME,
2078                 IFACE_IP_MODE_LOCAL_ONLY);
2079 
2080         mLooper.dispatchAll();
2081         verify(mHandler, never()).handleMessage(any(Message.class));
2082     }
2083 
2084     /**
2085      * Verify that onStopped is called only once for registered LOHS callers when
2086      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLING and
2087      * WIFI_AP_STATE_DISABLED when LOHS was enabled.
2088      */
2089     @Test
testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling()2090     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception {
2091         setupClientModeImplHandlerForPost();
2092 
2093         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2094         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2095         mWifiServiceImpl.checkAndStartWifi();
2096 
2097         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2098                 (IntentFilter) argThat(new IntentFilterMatcher()));
2099 
2100         registerLOHSRequestFull();
2101 
2102         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2103         mLooper.dispatchAll();
2104         verify(mHandler).handleMessage(mMessageCaptor.capture());
2105         Message message = mMessageCaptor.getValue();
2106         assertEquals(HOTSPOT_STARTED, message.what);
2107         reset(mHandler);
2108 
2109         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2110                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
2111                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2112         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2113                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
2114                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2115 
2116         mLooper.dispatchAll();
2117         verify(mHandler).handleMessage(mMessageCaptor.capture());
2118         message = mMessageCaptor.getValue();
2119         assertEquals(HOTSPOT_STOPPED, message.what);
2120     }
2121 
2122     /**
2123      * Verify that onFailed is called only once for registered LOHS callers when
2124      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED twice.
2125      */
2126     @Test
testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice()2127     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception {
2128         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2129         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2130         mWifiServiceImpl.checkAndStartWifi();
2131 
2132         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2133                 (IntentFilter) argThat(new IntentFilterMatcher()));
2134 
2135         registerLOHSRequestFull();
2136 
2137         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2138                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
2139                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2140         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2141                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
2142                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2143 
2144         mLooper.dispatchAll();
2145         verify(mHandler).handleMessage(mMessageCaptor.capture());
2146         Message message = mMessageCaptor.getValue();
2147         assertEquals(HOTSPOT_FAILED, message.what);
2148         assertEquals(ERROR_GENERIC, message.arg1);
2149     }
2150 
2151     /**
2152      * Verify that onFailed is called for all registered LOHS callers when
2153      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED.
2154      */
2155     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApFails()2156     public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception {
2157         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2158         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2159         mWifiServiceImpl.checkAndStartWifi();
2160 
2161         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2162                 (IntentFilter) argThat(new IntentFilterMatcher()));
2163 
2164         // make an additional request for this test
2165         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2166 
2167         registerLOHSRequestFull();
2168 
2169         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2170                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
2171                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2172         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2173                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
2174                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2175 
2176         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
2177         mLooper.dispatchAll();
2178         verify(mHandler).handleMessage(mMessageCaptor.capture());
2179         Message message = mMessageCaptor.getValue();
2180         assertEquals(HOTSPOT_FAILED, message.what);
2181         assertEquals(ERROR_GENERIC, message.arg1);
2182     }
2183 
2184     /**
2185      * Verify that onStopped is called for all registered LOHS callers when
2186      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
2187      * active.
2188      */
2189     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApStops()2190     public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception {
2191         setupClientModeImplHandlerForPost();
2192 
2193         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2194         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2195         mWifiServiceImpl.checkAndStartWifi();
2196 
2197         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2198                 (IntentFilter) argThat(new IntentFilterMatcher()));
2199 
2200         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2201 
2202         registerLOHSRequestFull();
2203 
2204         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2205         mLooper.dispatchAll();
2206         verify(mRequestInfo).sendHotspotStartedMessage(any());
2207         verify(mHandler).handleMessage(mMessageCaptor.capture());
2208         Message message = mMessageCaptor.getValue();
2209         assertEquals(HOTSPOT_STARTED, message.what);
2210         reset(mHandler);
2211 
2212         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2213                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
2214                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2215         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2216                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
2217                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2218 
2219         verify(mRequestInfo).sendHotspotStoppedMessage();
2220         mLooper.dispatchAll();
2221         verify(mHandler).handleMessage(mMessageCaptor.capture());
2222         message = mMessageCaptor.getValue();
2223         assertEquals(HOTSPOT_STOPPED, message.what);
2224     }
2225 
2226     /**
2227      * Verify that onFailed is called for all registered LOHS callers when
2228      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
2229      * not active.
2230      */
2231     @Test
testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive()2232     public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception {
2233         setupClientModeImplHandlerForPost();
2234 
2235         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2236         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2237         mWifiServiceImpl.checkAndStartWifi();
2238 
2239         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2240                 (IntentFilter) argThat(new IntentFilterMatcher()));
2241 
2242         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2243         mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2);
2244 
2245         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2246                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
2247                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2248         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2249                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
2250                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2251 
2252         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
2253         verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC);
2254     }
2255 
2256     /**
2257      * Verify that if we do not have registered LOHS requestors and we receive an update that LOHS
2258      * is up and ready for use, we tell WifiController to tear it down.  This can happen if softap
2259      * mode fails to come up properly and we get an onFailed message for a tethering call and we
2260      * had registered callers for LOHS.
2261      */
2262     @Test
testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode()2263     public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() {
2264         setupClientModeImplHandlerForPost();
2265 
2266         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2267         mLooper.dispatchAll();
2268 
2269         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
2270                 eq(WifiManager.IFACE_IP_MODE_TETHERED));
2271     }
2272 
2273     /**
2274      * Verify that all registered LOHS requestors are notified via a HOTSPOT_STARTED message that
2275      * the hotspot is up and ready to use.
2276      */
2277     @Test
testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()2278     public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()
2279             throws Exception {
2280         setupClientModeImplHandlerForPost();
2281 
2282         registerLOHSRequestFull();
2283 
2284         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2285 
2286         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2287         mLooper.dispatchAll();
2288         verify(mRequestInfo).sendHotspotStartedMessage(any(WifiConfiguration.class));
2289 
2290         mLooper.dispatchAll();
2291         verify(mHandler).handleMessage(mMessageCaptor.capture());
2292         Message message = mMessageCaptor.getValue();
2293         assertEquals(HOTSPOT_STARTED, message.what);
2294         assertNotNull((WifiConfiguration) message.obj);
2295     }
2296 
2297     /**
2298      * Verify that if a LOHS is already active, a new call to register a request will trigger the
2299      * onStarted callback.
2300      */
2301     @Test
testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()2302     public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()
2303             throws Exception {
2304         setupClientModeImplHandlerForPost();
2305 
2306         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2307 
2308         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2309         mLooper.dispatchAll();
2310 
2311         registerLOHSRequestFull();
2312 
2313         mLooper.dispatchAll();
2314 
2315         verify(mHandler).handleMessage(mMessageCaptor.capture());
2316         Message message = mMessageCaptor.getValue();
2317         assertEquals(HOTSPOT_STARTED, message.what);
2318         // since the first request was registered out of band, the config will be null
2319         assertNull((WifiConfiguration) message.obj);
2320     }
2321 
2322     /**
2323      * Verify that if a LOHS request is active and we receive an update with an ip mode
2324      * configuration error, callers are notified via the onFailed callback with the generic
2325      * error and are unregistered.
2326      */
2327     @Test
testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails()2328     public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception {
2329         setupClientModeImplHandlerForPost();
2330 
2331         registerLOHSRequestFull();
2332 
2333         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
2334         mLooper.dispatchAll();
2335 
2336         verify(mHandler).handleMessage(mMessageCaptor.capture());
2337         Message message = mMessageCaptor.getValue();
2338         assertEquals(HOTSPOT_FAILED, message.what);
2339         assertEquals(ERROR_GENERIC, message.arg1);
2340 
2341         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0),
2342                 eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
2343 
2344         // sendMessage should only happen once since the requestor should be unregistered
2345         reset(mHandler);
2346 
2347         // send HOTSPOT_FAILED message should only happen once since the requestor should be
2348         // unregistered
2349         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
2350         mLooper.dispatchAll();
2351         verify(mHandler, never()).handleMessage(any(Message.class));
2352     }
2353 
2354     /**
2355      * Verify that softap mode is stopped for tethering if we receive an update with an ip mode
2356      * configuration error.
2357      */
2358     @Test
testStopSoftApWhenIpConfigFails()2359     public void testStopSoftApWhenIpConfigFails() throws Exception {
2360         setupClientModeImplHandlerForPost();
2361 
2362         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
2363         mLooper.dispatchAll();
2364 
2365         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
2366                 eq(WifiManager.IFACE_IP_MODE_TETHERED));
2367     }
2368 
2369     /**
2370      * Verify that if a LOHS request is active and tethering starts, callers are notified on the
2371      * incompatible mode and are unregistered.
2372      */
2373     @Test
testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts()2374     public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception {
2375         setupClientModeImplHandlerForPost();
2376 
2377         registerLOHSRequestFull();
2378 
2379         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
2380         mLooper.dispatchAll();
2381 
2382         verify(mHandler).handleMessage(mMessageCaptor.capture());
2383         Message message = mMessageCaptor.getValue();
2384         assertEquals(HOTSPOT_FAILED, message.what);
2385         assertEquals(ERROR_INCOMPATIBLE_MODE, message.arg1);
2386 
2387         // sendMessage should only happen once since the requestor should be unregistered
2388         reset(mHandler);
2389 
2390         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
2391         mLooper.dispatchAll();
2392         verify(mHandler, never()).handleMessage(any(Message.class));
2393     }
2394 
2395     /**
2396      * Verify that if LOHS is disabled, a new call to register a request will not trigger the
2397      * onStopped callback.
2398      */
2399     @Test
testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback()2400     public void testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback()
2401             throws Exception {
2402         registerLOHSRequestFull();
2403         mLooper.dispatchAll();
2404 
2405         verify(mHandler, never()).handleMessage(any(Message.class));
2406     }
2407 
2408     /**
2409      * Verify that if a LOHS was active and then stopped, a new call to register a request will
2410      * not trigger the onStarted callback.
2411      */
2412     @Test
testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()2413     public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()
2414             throws Exception {
2415         setupClientModeImplHandlerForPost();
2416 
2417         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
2418         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
2419         mWifiServiceImpl.checkAndStartWifi();
2420         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
2421                 (IntentFilter) argThat(new IntentFilterMatcher()));
2422 
2423         // register a request so we don't drop the LOHS interface ip update
2424         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
2425 
2426         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2427         mLooper.dispatchAll();
2428 
2429         registerLOHSRequestFull();
2430         mLooper.dispatchAll();
2431 
2432         verify(mHandler).handleMessage(mMessageCaptor.capture());
2433         assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what);
2434 
2435         reset(mHandler);
2436 
2437         // now stop the hotspot
2438         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2439                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
2440                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2441         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
2442                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
2443                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
2444         mLooper.dispatchAll();
2445         verify(mHandler).handleMessage(mMessageCaptor.capture());
2446         assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what);
2447 
2448         reset(mHandler);
2449 
2450         // now register a new caller - they should not get the onStarted callback
2451         Messenger messenger2 = new Messenger(mHandler);
2452         IBinder binder2 = mock(IBinder.class);
2453 
2454         int result = mWifiServiceImpl.startLocalOnlyHotspot(messenger2, binder2, TEST_PACKAGE_NAME);
2455         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
2456         mLooper.dispatchAll();
2457 
2458         verify(mHandler, never()).handleMessage(any(Message.class));
2459     }
2460 
2461     /**
2462      * Verify that a call to startWatchLocalOnlyHotspot is only allowed from callers with the
2463      * signature only NETWORK_SETTINGS permission.
2464      *
2465      * This test is expecting the permission check to enforce the permission and throw a
2466      * SecurityException for callers without the permission.  This exception should be bubbled up to
2467      * the caller of startLocalOnlyHotspot.
2468      */
2469     @Test(expected = SecurityException.class)
testStartWatchLocalOnlyHotspotNotApprovedCaller()2470     public void testStartWatchLocalOnlyHotspotNotApprovedCaller() {
2471         doThrow(new SecurityException()).when(mContext)
2472                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2473                                                 eq("WifiService"));
2474         mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
2475     }
2476 
2477     /**
2478      * Verify that the call to startWatchLocalOnlyHotspot throws the UnsupportedOperationException
2479      * when called until the implementation is complete.
2480      */
2481     @Test(expected = UnsupportedOperationException.class)
testStartWatchLocalOnlyHotspotNotSupported()2482     public void testStartWatchLocalOnlyHotspotNotSupported() {
2483         mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
2484     }
2485 
2486     /**
2487      * Verify that a call to stopWatchLocalOnlyHotspot is only allowed from callers with the
2488      * signature only NETWORK_SETTINGS permission.
2489      */
2490     @Test(expected = SecurityException.class)
testStopWatchLocalOnlyHotspotNotApprovedCaller()2491     public void testStopWatchLocalOnlyHotspotNotApprovedCaller() {
2492         doThrow(new SecurityException()).when(mContext)
2493                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2494                                                 eq("WifiService"));
2495         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
2496     }
2497 
2498     /**
2499      * Verify that the call to stopWatchLocalOnlyHotspot throws the UnsupportedOperationException
2500      * until the implementation is complete.
2501      */
2502     @Test(expected = UnsupportedOperationException.class)
testStopWatchLocalOnlyHotspotNotSupported()2503     public void testStopWatchLocalOnlyHotspotNotSupported() {
2504         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
2505     }
2506 
2507     /**
2508      * Verify that the call to addOrUpdateNetwork for installing Passpoint profile is redirected
2509      * to the Passpoint specific API addOrUpdatePasspointConfiguration.
2510      */
2511     @Test
testAddPasspointProfileViaAddNetwork()2512     public void testAddPasspointProfileViaAddNetwork() throws Exception {
2513         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
2514         config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
2515 
2516         PackageManager pm = mock(PackageManager.class);
2517         when(pm.hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
2518         when(mContext.getPackageManager()).thenReturn(pm);
2519         when(pm.getApplicationInfo(any(), anyInt())).thenReturn(mApplicationInfo);
2520         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
2521                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
2522 
2523         when(mClientModeImpl.syncAddOrUpdatePasspointConfig(any(),
2524                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(
2525                 true);
2526         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
2527         verifyCheckChangePermission(TEST_PACKAGE_NAME);
2528         verify(mClientModeImpl).syncAddOrUpdatePasspointConfig(any(),
2529                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME));
2530         reset(mClientModeImpl);
2531 
2532         when(mClientModeImpl.syncAddOrUpdatePasspointConfig(any(),
2533                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(
2534                 false);
2535         assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
2536         verify(mClientModeImpl).syncAddOrUpdatePasspointConfig(any(),
2537                 any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME));
2538     }
2539 
2540     /**
2541      * Verify that the call to getAllMatchingFqdnsForScanResults is not redirected to specific API
2542      * syncGetAllMatchingFqdnsForScanResults when the caller doesn't have NETWORK_SETTINGS
2543      * permissions and NETWORK_SETUP_WIZARD.
2544      */
2545     @Test(expected = SecurityException.class)
testGetAllMatchingFqdnsForScanResultsWithoutPermissions()2546     public void testGetAllMatchingFqdnsForScanResultsWithoutPermissions() {
2547         mWifiServiceImpl.getAllMatchingFqdnsForScanResults(new ArrayList<>());
2548     }
2549 
2550     /**
2551      * Verify that the call to getWifiConfigsForPasspointProfiles is not redirected to specific API
2552      * syncGetWifiConfigsForPasspointProfiles when the caller doesn't have NETWORK_SETTINGS
2553      * permissions and NETWORK_SETUP_WIZARD.
2554      */
2555     @Test(expected = SecurityException.class)
testGetWifiConfigsForPasspointProfilesWithoutPermissions()2556     public void testGetWifiConfigsForPasspointProfilesWithoutPermissions() {
2557         mWifiServiceImpl.getWifiConfigsForPasspointProfiles(new ArrayList<>());
2558     }
2559 
2560     /**
2561      * Verify that the call to getMatchingOsuProviders is not redirected to specific API
2562      * syncGetMatchingOsuProviders when the caller doesn't have NETWORK_SETTINGS
2563      * permissions and NETWORK_SETUP_WIZARD.
2564      */
2565     @Test(expected = SecurityException.class)
testGetMatchingOsuProvidersWithoutPermissions()2566     public void testGetMatchingOsuProvidersWithoutPermissions() {
2567         mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
2568     }
2569 
2570     /**
2571      * Verify that the call to getMatchingPasspointConfigsForOsuProviders is not redirected to
2572      * specific API syncGetMatchingPasspointConfigsForOsuProviders when the caller doesn't have
2573      * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
2574      */
2575     @Test(expected = SecurityException.class)
testGetMatchingPasspointConfigsForOsuProvidersWithoutPermissions()2576     public void testGetMatchingPasspointConfigsForOsuProvidersWithoutPermissions() {
2577         mWifiServiceImpl.getMatchingPasspointConfigsForOsuProviders(new ArrayList<>());
2578     }
2579 
2580     /**
2581      * Verify that the call to startSubscriptionProvisioning is redirected to the Passpoint
2582      * specific API startSubscriptionProvisioning when the caller has the right permissions.
2583      */
2584     @Test
testStartSubscriptionProvisioningWithPermission()2585     public void testStartSubscriptionProvisioningWithPermission() throws Exception {
2586         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2587                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2588         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
2589                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2590 
2591         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
2592         verify(mClientModeImpl).syncStartSubscriptionProvisioning(anyInt(),
2593                 eq(mOsuProvider), eq(mProvisioningCallback), any());
2594     }
2595 
2596     /**
2597      * Verify that the call to startSubscriptionProvisioning is not directed to the Passpoint
2598      * specific API startSubscriptionProvisioning when the feature is not supported.
2599      */
2600     @Test(expected = UnsupportedOperationException.class)
testStartSubscriptionProvisioniningPasspointUnsupported()2601     public void testStartSubscriptionProvisioniningPasspointUnsupported() throws Exception {
2602         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2603                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2604         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
2605                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2606         when(mPackageManager.hasSystemFeature(
2607                 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false);
2608         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
2609     }
2610 
2611     /**
2612      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
2613      * specific API startSubscriptionProvisioning when the caller provides invalid arguments
2614      */
2615     @Test(expected = IllegalArgumentException.class)
testStartSubscriptionProvisioningWithInvalidProvider()2616     public void testStartSubscriptionProvisioningWithInvalidProvider() throws Exception {
2617         mWifiServiceImpl.startSubscriptionProvisioning(null, mProvisioningCallback);
2618     }
2619 
2620 
2621     /**
2622      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
2623      * specific API startSubscriptionProvisioning when the caller provides invalid callback
2624      */
2625     @Test(expected = IllegalArgumentException.class)
testStartSubscriptionProvisioningWithInvalidCallback()2626     public void testStartSubscriptionProvisioningWithInvalidCallback() throws Exception {
2627         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, null);
2628     }
2629 
2630     /**
2631      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
2632      * specific API startSubscriptionProvisioning when the caller doesn't have NETWORK_SETTINGS
2633      * permissions and NETWORK_SETUP_WIZARD.
2634      */
2635     @Test(expected = SecurityException.class)
testStartSubscriptionProvisioningWithoutPermissions()2636     public void testStartSubscriptionProvisioningWithoutPermissions() throws Exception {
2637         when(mContext.checkCallingOrSelfPermission(
2638                 eq(android.Manifest.permission.NETWORK_SETTINGS))).thenReturn(
2639                 PackageManager.PERMISSION_DENIED);
2640         when(mContext.checkSelfPermission(
2641                 eq(android.Manifest.permission.NETWORK_SETUP_WIZARD))).thenReturn(
2642                 PackageManager.PERMISSION_DENIED);
2643 
2644         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
2645     }
2646 
2647     /**
2648      * Verify that the call to getPasspointConfigurations is not redirected to specific API
2649      * syncGetPasspointConfigs when the caller doesn't have NETWORK_SETTINGS permissions and
2650      * NETWORK_SETUP_WIZARD.
2651      */
2652     @Test(expected = SecurityException.class)
testGetPasspointConfigurationsWithOutPermissions()2653     public void testGetPasspointConfigurationsWithOutPermissions() {
2654         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
2655         when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
2656 
2657         mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
2658     }
2659 
2660     /**
2661      * Verify that getPasspointConfigurations called by apps that has invalid package will
2662      * throw {@link SecurityException}.
2663      */
2664     @Test(expected = SecurityException.class)
testGetPasspointConfigurationWithInvalidPackage()2665     public void testGetPasspointConfigurationWithInvalidPackage() {
2666         doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(),
2667                 eq(TEST_PACKAGE_NAME));
2668         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
2669         when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(true);
2670 
2671         mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
2672     }
2673 
2674     /**
2675      * Verify that getPasspointConfigurations called by apps targeting below Q SDK will return
2676      * empty list if the caller doesn't have NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
2677      */
2678     @Test
testGetPasspointConfigurationForAppsTargetingBelowQSDK()2679     public void testGetPasspointConfigurationForAppsTargetingBelowQSDK() {
2680         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
2681         when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
2682         when(mWifiPermissionsUtil.isTargetSdkLessThan(eq(TEST_PACKAGE_NAME),
2683                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
2684 
2685         List<PasspointConfiguration> result = mWifiServiceImpl.getPasspointConfigurations(
2686                 TEST_PACKAGE_NAME);
2687         assertNotNull(result);
2688         assertEquals(0, result.size());
2689     }
2690 
2691     /**
2692      * Verify that the call to removePasspointConfiguration is not redirected to specific API
2693      * syncRemovePasspointConfig when the caller doesn't have NETWORK_SETTINGS and
2694      * NETWORK_CARRIER_PROVISIONING permission.
2695      */
2696     @Test(expected = SecurityException.class)
testRemovePasspointConfigurationWithOutPermissions()2697     public void testRemovePasspointConfigurationWithOutPermissions() {
2698         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
2699         when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
2700                 false);
2701 
2702         mWifiServiceImpl.removePasspointConfiguration(null, null);
2703     }
2704 
2705     /**
2706      * Verify that the call to removePasspointConfiguration for apps targeting below Q SDK will
2707      * return false if the caller doesn't have NETWORK_SETTINGS and NETWORK_CARRIER_PROVISIONING
2708      * permission.
2709      */
2710     @Test
testRemovePasspointConfigurationForAppsTargetingBelowQSDK()2711     public void testRemovePasspointConfigurationForAppsTargetingBelowQSDK() {
2712         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
2713         when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
2714                 false);
2715         when(mWifiPermissionsUtil.isTargetSdkLessThan(isNull(),
2716                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
2717 
2718         assertFalse(mWifiServiceImpl.removePasspointConfiguration(null, null));
2719     }
2720 
2721     /**
2722      * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from
2723      * callers with the signature only NETWORK_SETTINGS permission.
2724      */
2725     @Test(expected = SecurityException.class)
testRestoreBackupDataNotApprovedCaller()2726     public void testRestoreBackupDataNotApprovedCaller() {
2727         doThrow(new SecurityException()).when(mContext)
2728                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2729                         eq("WifiService"));
2730         mWifiServiceImpl.restoreBackupData(null);
2731         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class));
2732     }
2733 
2734     /**
2735      * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is
2736      * only allowed from callers with the signature only NETWORK_SETTINGS permission.
2737      */
2738     @Test(expected = SecurityException.class)
testRestoreSupplicantBackupDataNotApprovedCaller()2739     public void testRestoreSupplicantBackupDataNotApprovedCaller() {
2740         doThrow(new SecurityException()).when(mContext)
2741                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2742                         eq("WifiService"));
2743         mWifiServiceImpl.restoreSupplicantBackupData(null, null);
2744         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData(
2745                 any(byte[].class), any(byte[].class));
2746     }
2747 
2748     /**
2749      * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from
2750      * callers with the signature only NETWORK_SETTINGS permission.
2751      */
2752     @Test(expected = SecurityException.class)
testRetrieveBackupDataNotApprovedCaller()2753     public void testRetrieveBackupDataNotApprovedCaller() {
2754         doThrow(new SecurityException()).when(mContext)
2755                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2756                         eq("WifiService"));
2757         mWifiServiceImpl.retrieveBackupData();
2758         verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class));
2759     }
2760 
2761     /**
2762      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is allowed from
2763      * callers with the signature only NETWORK_SETTINGS permission.
2764      */
2765     @Test
testEnableVerboseLoggingWithNetworkSettingsPermission()2766     public void testEnableVerboseLoggingWithNetworkSettingsPermission() {
2767         doNothing().when(mContext)
2768                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2769                         eq("WifiService"));
2770         // Vebose logging is enabled first in the constructor for WifiServiceImpl, so reset
2771         // before invocation.
2772         reset(mClientModeImpl);
2773         mWifiServiceImpl.enableVerboseLogging(1);
2774         verify(mClientModeImpl).enableVerboseLogging(anyInt());
2775     }
2776 
2777     /**
2778      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is not allowed from
2779      * callers without the signature only NETWORK_SETTINGS permission.
2780      */
2781     @Test(expected = SecurityException.class)
testEnableVerboseLoggingWithNoNetworkSettingsPermission()2782     public void testEnableVerboseLoggingWithNoNetworkSettingsPermission() {
2783         doThrow(new SecurityException()).when(mContext)
2784                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2785                         eq("WifiService"));
2786         // Vebose logging is enabled first in the constructor for WifiServiceImpl, so reset
2787         // before invocation.
2788         reset(mClientModeImpl);
2789         mWifiServiceImpl.enableVerboseLogging(1);
2790         verify(mClientModeImpl, never()).enableVerboseLogging(anyInt());
2791     }
2792 
2793     /**
2794      * Helper to test handling of async messages by wifi service when the message comes from an
2795      * app without {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
2796      */
verifyAsyncChannelMessageHandlingWithoutChangePermisson( int requestMsgWhat, int expectedReplyMsgwhat)2797     private void verifyAsyncChannelMessageHandlingWithoutChangePermisson(
2798             int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException {
2799         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
2800 
2801         int uidWithoutPermission = 5;
2802         when(mWifiPermissionsUtil.checkChangePermission(eq(uidWithoutPermission)))
2803                 .thenReturn(false);
2804 
2805         Message request = Message.obtain();
2806         request.what = requestMsgWhat;
2807         request.sendingUid = uidWithoutPermission;
2808 
2809         mLooper.startAutoDispatch();
2810         Message reply = tester.sendMessageSynchronously(request);
2811         mLooper.stopAutoDispatch();
2812 
2813         verify(mClientModeImpl, never()).sendMessage(any(Message.class));
2814         assertEquals(expectedReplyMsgwhat, reply.what);
2815         assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1);
2816     }
2817 
2818     /**
2819      * Helper to test handling of async messages by wifi service when the message comes from an
2820      * app without one of the privileged permissions.
2821      */
verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons( int requestMsgWhat, int expectedReplyMsgwhat)2822     private void verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
2823             int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException {
2824         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
2825 
2826         int uidWithoutPermission = 5;
2827         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2828                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
2829         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
2830                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
2831         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_STACK),
2832                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
2833 
2834         Message request = Message.obtain();
2835         request.what = requestMsgWhat;
2836         request.sendingUid = uidWithoutPermission;
2837 
2838         mLooper.startAutoDispatch();
2839         Message reply = tester.sendMessageSynchronously(request);
2840         mLooper.stopAutoDispatch();
2841 
2842         verify(mClientModeImpl, never()).sendMessage(any(Message.class));
2843         assertEquals(expectedReplyMsgwhat, reply.what);
2844         assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1);
2845     }
2846 
2847     /**
2848      * Verify that the CONNECT_NETWORK message received from an app without
2849      * one of the privileged permission is rejected with the correct error code.
2850      */
2851     @Test
testConnectNetworkWithoutPrivilegedPermission()2852     public void testConnectNetworkWithoutPrivilegedPermission() throws Exception {
2853         verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
2854                 WifiManager.CONNECT_NETWORK, WifiManager.CONNECT_NETWORK_FAILED);
2855     }
2856 
2857     /**
2858      * Verify that the FORGET_NETWORK message received from an app without
2859      * one of the privileged permission is rejected with the correct error code.
2860      */
2861     @Test
testForgetNetworkWithoutPrivilegedPermission()2862     public void testForgetNetworkWithoutPrivilegedPermission() throws Exception {
2863         verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
2864                 WifiManager.SAVE_NETWORK, WifiManager.SAVE_NETWORK_FAILED);
2865     }
2866 
2867     /**
2868      * Verify that the DISABLE_NETWORK message received from an app without
2869      * one of the privileged permission is rejected with the correct error code.
2870      */
2871     @Test
testDisableNetworkWithoutPrivilegedPermission()2872     public void testDisableNetworkWithoutPrivilegedPermission() throws Exception {
2873         verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
2874                 WifiManager.DISABLE_NETWORK, WifiManager.DISABLE_NETWORK_FAILED);
2875     }
2876 
2877     /**
2878      * Verify that the RSSI_PKTCNT_FETCH message received from an app without
2879      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
2880      * error code.
2881      */
2882     @Test
testRssiPktcntFetchWithoutChangePermission()2883     public void testRssiPktcntFetchWithoutChangePermission() throws Exception {
2884         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
2885                 WifiManager.RSSI_PKTCNT_FETCH, WifiManager.RSSI_PKTCNT_FETCH_FAILED);
2886     }
2887 
2888     /**
2889      * Helper to test handling of async messages by wifi service when the message comes from an
2890      * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
2891      */
verifyAsyncChannelMessageHandlingWithChangePermisson( int requestMsgWhat, Object requestMsgObj)2892     private void verifyAsyncChannelMessageHandlingWithChangePermisson(
2893             int requestMsgWhat, Object requestMsgObj) throws RemoteException {
2894         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
2895 
2896         when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true);
2897 
2898         Message request = Message.obtain();
2899         request.what = requestMsgWhat;
2900         request.obj = requestMsgObj;
2901 
2902         tester.sendMessage(request);
2903         mLooper.dispatchAll();
2904 
2905         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
2906         verify(mClientModeImpl).sendMessage(messageArgumentCaptor.capture());
2907         assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what);
2908     }
2909 
2910     /**
2911      * Helper to test handling of async messages by wifi service when the message comes from an
2912      * app with one of the  privileged permissions.
2913      */
verifyAsyncChannelMessageHandlingWithPrivilegedPermissions( int requestMsgWhat, Object requestMsgObj)2914     private void verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
2915             int requestMsgWhat, Object requestMsgObj) throws RemoteException {
2916         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
2917 
2918         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
2919                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
2920 
2921         Message request = Message.obtain();
2922         request.what = requestMsgWhat;
2923         request.obj = requestMsgObj;
2924 
2925         tester.sendMessage(request);
2926         mLooper.dispatchAll();
2927 
2928         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
2929         verify(mClientModeImpl).sendMessage(messageArgumentCaptor.capture());
2930         assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what);
2931     }
2932 
2933     /**
2934      * Verify that the CONNECT_NETWORK message received from an app with
2935      * one of the privileged permission is forwarded to ClientModeImpl.
2936      */
2937     @Test
testConnectNetworkWithPrivilegedPermission()2938     public void testConnectNetworkWithPrivilegedPermission() throws Exception {
2939         verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
2940                 WifiManager.CONNECT_NETWORK, new WifiConfiguration());
2941     }
2942 
2943     /**
2944      * Verify that the SAVE_NETWORK message received from an app with
2945      * one of the privileged permission is forwarded to ClientModeImpl.
2946      */
2947     @Test
testSaveNetworkWithPrivilegedPermission()2948     public void testSaveNetworkWithPrivilegedPermission() throws Exception {
2949         verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
2950                 WifiManager.SAVE_NETWORK, new WifiConfiguration());
2951     }
2952 
2953     /**
2954      * Verify that the DISABLE_NETWORK message received from an app with
2955      * one of the privileged permission is forwarded to ClientModeImpl.
2956      */
2957     @Test
testDisableNetworkWithPrivilegedPermission()2958     public void testDisableNetworkWithPrivilegedPermission() throws Exception {
2959         verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
2960                 WifiManager.DISABLE_NETWORK, new Object());
2961     }
2962 
2963     /**
2964      * Verify that the RSSI_PKTCNT_FETCH message received from an app with
2965      * one of the privileged permission is forwarded to ClientModeImpl.
2966      */
2967     @Test
testRssiPktcntFetchWithChangePermission()2968     public void testRssiPktcntFetchWithChangePermission() throws Exception {
2969         verifyAsyncChannelMessageHandlingWithChangePermisson(
2970                 WifiManager.RSSI_PKTCNT_FETCH, new Object());
2971     }
2972 
2973     /**
2974      * Verify that setCountryCode() calls WifiCountryCode object on succeess.
2975      */
2976     @Test
testSetCountryCode()2977     public void testSetCountryCode() throws Exception {
2978         mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
2979         verify(mWifiCountryCode).setCountryCode(TEST_COUNTRY_CODE);
2980     }
2981 
2982     /**
2983      * Verify that setCountryCode() fails and doesn't call WifiCountryCode object
2984      * if the caller doesn't have CONNECTIVITY_INTERNAL permission.
2985      */
2986     @Test(expected = SecurityException.class)
testSetCountryCodeFailsWithoutConnectivityInternalPermission()2987     public void testSetCountryCodeFailsWithoutConnectivityInternalPermission() throws Exception {
2988         doThrow(new SecurityException()).when(mContext)
2989                 .enforceCallingOrSelfPermission(
2990                         eq(android.Manifest.permission.CONNECTIVITY_INTERNAL),
2991                         eq("ConnectivityService"));
2992         mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
2993         verify(mWifiCountryCode, never()).setCountryCode(TEST_COUNTRY_CODE);
2994     }
2995 
setupClientModeImplHandlerForPost()2996     private void setupClientModeImplHandlerForPost() {
2997         when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
2998     }
2999 
3000     /**
3001      * Set the wifi state machine mock to return a handler created on test thread.
3002      */
setupClientModeImplHandlerForRunWithScissors()3003     private void setupClientModeImplHandlerForRunWithScissors() {
3004         HandlerThread handlerThread = createAndStartHandlerThreadForRunWithScissors();
3005         mHandlerSpyForCmiRunWithScissors = spy(handlerThread.getThreadHandler());
3006         when(mWifiInjector.getClientModeImplHandler())
3007                 .thenReturn(mHandlerSpyForCmiRunWithScissors);
3008     }
3009 
createAndStartHandlerThreadForRunWithScissors()3010     private HandlerThread createAndStartHandlerThreadForRunWithScissors() {
3011         HandlerThread handlerThread = new HandlerThread("ServiceHandlerThreadForTest");
3012         handlerThread.start();
3013         return handlerThread;
3014     }
3015 
3016     /**
3017      * Tests the scenario when a scan request arrives while the device is idle. In this case
3018      * the scan is done when idle mode ends.
3019      */
3020     @Test
testHandleDelayedScanAfterIdleMode()3021     public void testHandleDelayedScanAfterIdleMode() throws Exception {
3022         setupClientModeImplHandlerForRunWithScissors();
3023         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
3024         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
3025         mWifiServiceImpl.checkAndStartWifi();
3026         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3027                 (IntentFilter) argThat(new IdleModeIntentMatcher()));
3028 
3029         // Tell the wifi service that the device became idle.
3030         when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
3031         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
3032 
3033         // Send a scan request while the device is idle.
3034         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
3035         // No scans must be made yet as the device is idle.
3036         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
3037 
3038         // Tell the wifi service that idle mode ended.
3039         when(mPowerManager.isDeviceIdleMode()).thenReturn(false);
3040         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
3041 
3042         // Must scan now.
3043         verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME);
3044         // The app ops check is executed with this package's identity (not the identity of the
3045         // original remote caller who requested the scan while idle).
3046         verify(mAppOpsManager).noteOp(
3047                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3048 
3049         // Send another scan request. The device is not idle anymore, so it must be executed
3050         // immediately.
3051         assertTrue(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
3052         verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
3053     }
3054 
3055     /**
3056      * Verify that if the caller has NETWORK_SETTINGS permission, then it doesn't need
3057      * CHANGE_WIFI_STATE permission.
3058      * @throws Exception
3059      */
3060     @Test
testDisconnectWithNetworkSettingsPerm()3061     public void testDisconnectWithNetworkSettingsPerm() throws Exception {
3062         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3063                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3064         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
3065                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
3066         doThrow(new SecurityException()).when(mAppOpsManager)
3067                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3068         assertTrue(mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME));
3069         verify(mClientModeImpl).disconnectCommand();
3070     }
3071 
3072     /**
3073      * Verify that if the caller doesn't have NETWORK_SETTINGS permission, it could still
3074      * get access with the CHANGE_WIFI_STATE permission.
3075      * @throws Exception
3076      */
3077     @Test
testDisconnectWithChangeWifiStatePerm()3078     public void testDisconnectWithChangeWifiStatePerm() throws Exception {
3079         assertFalse(mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME));
3080         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3081         verify(mClientModeImpl, never()).disconnectCommand();
3082     }
3083 
3084     /**
3085      * Verify that the operation fails if the caller has neither NETWORK_SETTINGS or
3086      * CHANGE_WIFI_STATE permissions.
3087      * @throws Exception
3088      */
3089     @Test
testDisconnectRejected()3090     public void testDisconnectRejected() throws Exception {
3091         doThrow(new SecurityException()).when(mAppOpsManager)
3092                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3093         try {
3094             mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME);
3095             fail();
3096         } catch (SecurityException e) {
3097 
3098         }
3099         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3100         verify(mClientModeImpl, never()).disconnectCommand();
3101     }
3102 
3103     @Test
testPackageRemovedBroadcastHandling()3104     public void testPackageRemovedBroadcastHandling() {
3105         when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
3106         mWifiServiceImpl.checkAndStartWifi();
3107         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3108                 argThat((IntentFilter filter) ->
3109                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
3110 
3111         int uid = TEST_UID;
3112         String packageName = TEST_PACKAGE_NAME;
3113         // Send the broadcast
3114         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
3115         intent.putExtra(Intent.EXTRA_UID, uid);
3116         intent.setData(Uri.fromParts("package", packageName, ""));
3117         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3118 
3119         verify(mClientModeImpl).removeAppConfigs(packageName, uid);
3120 
3121         mLooper.dispatchAll();
3122         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
3123         verify(mWifiNetworkSuggestionsManager).removeApp(packageName);
3124         verify(mClientModeImpl).removeNetworkRequestUserApprovedAccessPointsForApp(packageName);
3125         verify(mPasspointManager).removePasspointProviderWithPackage(packageName);
3126     }
3127 
3128     @Test
testPackageRemovedBroadcastHandlingWithNoUid()3129     public void testPackageRemovedBroadcastHandlingWithNoUid() {
3130         when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
3131         mWifiServiceImpl.checkAndStartWifi();
3132         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3133                 argThat((IntentFilter filter) ->
3134                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
3135 
3136         String packageName = TEST_PACKAGE_NAME;
3137         // Send the broadcast
3138         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
3139         intent.setData(Uri.fromParts("package", packageName, ""));
3140         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3141 
3142         verify(mClientModeImpl, never()).removeAppConfigs(anyString(), anyInt());
3143 
3144         mLooper.dispatchAll();
3145         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
3146         verify(mWifiNetworkSuggestionsManager, never()).removeApp(anyString());
3147         verify(mClientModeImpl, never()).removeNetworkRequestUserApprovedAccessPointsForApp(
3148                 packageName);
3149         verify(mPasspointManager, never()).removePasspointProviderWithPackage(anyString());
3150     }
3151 
3152     @Test
testPackageRemovedBroadcastHandlingWithNoPackageName()3153     public void testPackageRemovedBroadcastHandlingWithNoPackageName() {
3154         when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
3155         mWifiServiceImpl.checkAndStartWifi();
3156         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3157                 argThat((IntentFilter filter) ->
3158                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
3159 
3160         int uid = TEST_UID;
3161         // Send the broadcast
3162         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
3163         intent.putExtra(Intent.EXTRA_UID, uid);
3164         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3165 
3166         verify(mClientModeImpl, never()).removeAppConfigs(anyString(), anyInt());
3167 
3168         mLooper.dispatchAll();
3169         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
3170         verify(mWifiNetworkSuggestionsManager, never()).removeApp(anyString());
3171         verify(mClientModeImpl, never()).removeNetworkRequestUserApprovedAccessPointsForApp(
3172                 anyString());
3173         verify(mPasspointManager, never()).removePasspointProviderWithPackage(anyString());
3174     }
3175 
3176     @Test
testUserRemovedBroadcastHandling()3177     public void testUserRemovedBroadcastHandling() {
3178         mWifiServiceImpl.checkAndStartWifi();
3179         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3180                 argThat((IntentFilter filter) ->
3181                         filter.hasAction(Intent.ACTION_USER_REMOVED)));
3182 
3183         int userHandle = TEST_USER_HANDLE;
3184         // Send the broadcast
3185         Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
3186         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
3187         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3188 
3189         verify(mClientModeImpl).removeUserConfigs(userHandle);
3190     }
3191 
3192     @Test
testUserRemovedBroadcastHandlingWithWrongIntentAction()3193     public void testUserRemovedBroadcastHandlingWithWrongIntentAction() {
3194         mWifiServiceImpl.checkAndStartWifi();
3195         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3196                 argThat((IntentFilter filter) ->
3197                         filter.hasAction(Intent.ACTION_USER_REMOVED)));
3198 
3199         int userHandle = TEST_USER_HANDLE;
3200         // Send the broadcast with wrong action
3201         Intent intent = new Intent(Intent.ACTION_USER_FOREGROUND);
3202         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
3203         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3204 
3205         verify(mClientModeImpl, never()).removeUserConfigs(userHandle);
3206     }
3207 
3208     /**
3209      * Test for needs5GHzToAnyApBandConversion returns true.  Requires the NETWORK_SETTINGS
3210      * permission.
3211      */
3212     @Test
testNeeds5GHzToAnyApBandConversionReturnedTrue()3213     public void testNeeds5GHzToAnyApBandConversionReturnedTrue() {
3214         when(mResources.getBoolean(
3215                 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any)))
3216                 .thenReturn(true);
3217         assertTrue(mWifiServiceImpl.needs5GHzToAnyApBandConversion());
3218 
3219         verify(mContext).enforceCallingOrSelfPermission(
3220                 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService"));
3221     }
3222 
3223     /**
3224      * Test for needs5GHzToAnyApBandConversion returns false.  Requires the NETWORK_SETTINGS
3225      * permission.
3226      */
3227     @Test
testNeeds5GHzToAnyApBandConversionReturnedFalse()3228     public void testNeeds5GHzToAnyApBandConversionReturnedFalse() {
3229         when(mResources.getBoolean(
3230                 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any)))
3231                 .thenReturn(false);
3232 
3233         assertFalse(mWifiServiceImpl.needs5GHzToAnyApBandConversion());
3234 
3235         verify(mContext).enforceCallingOrSelfPermission(
3236                 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService"));
3237     }
3238 
3239     /**
3240      * The API impl for needs5GHzToAnyApBandConversion requires the NETWORK_SETTINGS permission,
3241      * verify an exception is thrown without holding the permission.
3242      */
3243     @Test
testNeeds5GHzToAnyApBandConversionThrowsWithoutProperPermissions()3244     public void testNeeds5GHzToAnyApBandConversionThrowsWithoutProperPermissions() {
3245         doThrow(new SecurityException()).when(mContext)
3246                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3247                                                 eq("WifiService"));
3248 
3249         try {
3250             mWifiServiceImpl.needs5GHzToAnyApBandConversion();
3251             // should have thrown an exception - fail test
3252             fail();
3253         } catch (SecurityException e) {
3254             // expected
3255         }
3256     }
3257 
3258 
3259     private class IdleModeIntentMatcher implements ArgumentMatcher<IntentFilter> {
3260         @Override
matches(IntentFilter filter)3261         public boolean matches(IntentFilter filter) {
3262             return filter.hasAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
3263         }
3264     }
3265 
3266     /**
3267      * Verifies that enforceChangePermission(String package) is called and the caller doesn't
3268      * have NETWORK_SETTINGS permission
3269      */
verifyCheckChangePermission(String callingPackageName)3270     private void verifyCheckChangePermission(String callingPackageName) {
3271         verify(mContext, atLeastOnce())
3272                 .checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3273                         anyInt(), anyInt());
3274         verify(mContext, atLeastOnce()).enforceCallingOrSelfPermission(
3275                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
3276         verify(mAppOpsManager, atLeastOnce()).noteOp(
3277                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), callingPackageName);
3278     }
3279 
createValidSoftApConfiguration()3280     private WifiConfiguration createValidSoftApConfiguration() {
3281         WifiConfiguration apConfig = new WifiConfiguration();
3282         apConfig.SSID = "TestAp";
3283         apConfig.preSharedKey = "thisIsABadPassword";
3284         apConfig.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
3285         apConfig.apBand = WifiConfiguration.AP_BAND_2GHZ;
3286 
3287         return apConfig;
3288     }
3289 
3290     /**
3291      * Verifies that sim state change does not set or reset the country code
3292      */
3293     @Test
testSimStateChangeDoesNotResetCountryCode()3294     public void testSimStateChangeDoesNotResetCountryCode() {
3295         mWifiServiceImpl.checkAndStartWifi();
3296         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
3297                 (IntentFilter) argThat((IntentFilter filter) ->
3298                         filter.hasAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED)));
3299 
3300         int userHandle = TEST_USER_HANDLE;
3301         // Send the broadcast
3302         Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
3303         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
3304         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
3305         verifyNoMoreInteractions(mWifiCountryCode);
3306     }
3307 
3308     /**
3309      * Verify calls to notify users of a softap config change check the NETWORK_SETTINGS permission.
3310      */
3311     @Test
testNotifyUserOfApBandConversionChecksNetworkSettingsPermission()3312     public void testNotifyUserOfApBandConversionChecksNetworkSettingsPermission() {
3313         mWifiServiceImpl.notifyUserOfApBandConversion(TEST_PACKAGE_NAME);
3314         verify(mContext).enforceCallingOrSelfPermission(
3315                 eq(android.Manifest.permission.NETWORK_SETTINGS),
3316                 eq("WifiService"));
3317         verify(mWifiApConfigStore).notifyUserOfApBandConversion(eq(TEST_PACKAGE_NAME));
3318     }
3319 
3320     /**
3321      * Verify calls to notify users do not trigger a notification when NETWORK_SETTINGS is not held
3322      * by the caller.
3323      */
3324     @Test
testNotifyUserOfApBandConversionThrowsExceptionWithoutNetworkSettingsPermission()3325     public void testNotifyUserOfApBandConversionThrowsExceptionWithoutNetworkSettingsPermission() {
3326         doThrow(new SecurityException()).when(mContext)
3327                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3328                                                 eq("WifiService"));
3329         try {
3330             mWifiServiceImpl.notifyUserOfApBandConversion(TEST_PACKAGE_NAME);
3331             fail("Expected Security exception");
3332         } catch (SecurityException e) { }
3333     }
3334 
3335     /**
3336      * Verify that a call to registerTrafficStateCallback throws a SecurityException if the caller
3337      * does not have NETWORK_SETTINGS permission.
3338      */
3339     @Test
registerTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions()3340     public void registerTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions() {
3341         doThrow(new SecurityException()).when(mContext)
3342                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3343                         eq("WifiService"));
3344         try {
3345             mWifiServiceImpl.registerTrafficStateCallback(mAppBinder, mTrafficStateCallback,
3346                     TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
3347             fail("expected SecurityException");
3348         } catch (SecurityException expected) {
3349         }
3350     }
3351 
3352     /**
3353      * Verify that a call to registerTrafficStateCallback throws an IllegalArgumentException if the
3354      * parameters are not provided.
3355      */
3356     @Test
registerTrafficStateCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()3357     public void registerTrafficStateCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
3358         try {
3359             mWifiServiceImpl.registerTrafficStateCallback(
3360                     mAppBinder, null, TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
3361             fail("expected IllegalArgumentException");
3362         } catch (IllegalArgumentException expected) {
3363         }
3364     }
3365 
3366     /**
3367      * Verify that a call to unregisterTrafficStateCallback throws a SecurityException if the caller
3368      * does not have NETWORK_SETTINGS permission.
3369      */
3370     @Test
unregisterTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions()3371     public void unregisterTrafficStateCallbackThrowsSecurityExceptionOnMissingPermissions() {
3372         doThrow(new SecurityException()).when(mContext)
3373                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3374                         eq("WifiService"));
3375         try {
3376             mWifiServiceImpl.unregisterTrafficStateCallback(TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
3377             fail("expected SecurityException");
3378         } catch (SecurityException expected) {
3379         }
3380     }
3381 
3382     /**
3383      * Verify that registerTrafficStateCallback adds callback to {@link WifiTrafficPoller}.
3384      */
3385     @Test
registerTrafficStateCallbackAndVerify()3386     public void registerTrafficStateCallbackAndVerify() throws Exception {
3387         setupClientModeImplHandlerForPost();
3388 
3389         mWifiServiceImpl.registerTrafficStateCallback(
3390                 mAppBinder, mTrafficStateCallback, TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
3391         mLooper.dispatchAll();
3392         verify(mWifiTrafficPoller).addCallback(
3393                 mAppBinder, mTrafficStateCallback, TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
3394     }
3395 
3396     /**
3397      * Verify that unregisterTrafficStateCallback removes callback from {@link WifiTrafficPoller}.
3398      */
3399     @Test
unregisterTrafficStateCallbackAndVerify()3400     public void unregisterTrafficStateCallbackAndVerify() throws Exception {
3401         setupClientModeImplHandlerForPost();
3402 
3403         mWifiServiceImpl.unregisterTrafficStateCallback(0);
3404         mLooper.dispatchAll();
3405         verify(mWifiTrafficPoller).removeCallback(0);
3406     }
3407 
3408     /**
3409      * Verify that a call to registerNetworkRequestMatchCallback throws a SecurityException if the
3410      * caller does not have NETWORK_SETTINGS permission.
3411      */
3412     @Test
registerNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions()3413     public void registerNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() {
3414         doThrow(new SecurityException()).when(mContext)
3415                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3416                         eq("WifiService"));
3417         try {
3418             mWifiServiceImpl.registerNetworkRequestMatchCallback(mAppBinder,
3419                     mNetworkRequestMatchCallback,
3420                     TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3421             fail("expected SecurityException");
3422         } catch (SecurityException expected) {
3423         }
3424     }
3425 
3426     /**
3427      * Verify that a call to registerNetworkRequestMatchCallback throws an IllegalArgumentException
3428      * if the parameters are not provided.
3429      */
3430     @Test
3431     public void
registerNetworkRequestMatchCallbackThrowsIllegalArgumentExceptionOnInvalidArguments()3432             registerNetworkRequestMatchCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
3433         try {
3434             mWifiServiceImpl.registerNetworkRequestMatchCallback(
3435                     mAppBinder, null, TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3436             fail("expected IllegalArgumentException");
3437         } catch (IllegalArgumentException expected) {
3438         }
3439     }
3440 
3441     /**
3442      * Verify that a call to unregisterNetworkRequestMatchCallback throws a SecurityException if the
3443      * caller does not have NETWORK_SETTINGS permission.
3444      */
3445     @Test
unregisterNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions()3446     public void unregisterNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() {
3447         doThrow(new SecurityException()).when(mContext)
3448                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3449                         eq("WifiService"));
3450         try {
3451             mWifiServiceImpl.unregisterNetworkRequestMatchCallback(
3452                     TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3453             fail("expected SecurityException");
3454         } catch (SecurityException expected) {
3455         }
3456     }
3457 
3458     /**
3459      * Verify that registerNetworkRequestMatchCallback adds callback to
3460      * {@link ClientModeImpl}.
3461      */
3462     @Test
registerNetworkRequestMatchCallbackAndVerify()3463     public void registerNetworkRequestMatchCallbackAndVerify() throws Exception {
3464         setupClientModeImplHandlerForPost();
3465 
3466         mWifiServiceImpl.registerNetworkRequestMatchCallback(
3467                 mAppBinder, mNetworkRequestMatchCallback,
3468                 TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3469         mLooper.dispatchAll();
3470         verify(mClientModeImpl).addNetworkRequestMatchCallback(
3471                 mAppBinder, mNetworkRequestMatchCallback,
3472                 TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3473     }
3474 
3475     /**
3476      * Verify that unregisterNetworkRequestMatchCallback removes callback from
3477      * {@link ClientModeImpl}.
3478      */
3479     @Test
unregisterNetworkRequestMatchCallbackAndVerify()3480     public void unregisterNetworkRequestMatchCallbackAndVerify() throws Exception {
3481         setupClientModeImplHandlerForPost();
3482 
3483         mWifiServiceImpl.unregisterNetworkRequestMatchCallback(
3484                 TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3485         mLooper.dispatchAll();
3486         verify(mClientModeImpl).removeNetworkRequestMatchCallback(
3487                 TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
3488     }
3489 
3490     /**
3491      * Verify that Wifi configuration and Passpoint configuration are removed in factoryReset.
3492      */
3493     @Test
testFactoryReset()3494     public void testFactoryReset() throws Exception {
3495         setupClientModeImplHandlerForPost();
3496 
3497         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3498                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3499         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
3500         final String fqdn = "example.com";
3501         WifiConfiguration network = WifiConfigurationTestUtil.createOpenNetwork();
3502         PasspointConfiguration config = new PasspointConfiguration();
3503         HomeSp homeSp = new HomeSp();
3504         homeSp.setFqdn(fqdn);
3505         config.setHomeSp(homeSp);
3506 
3507         mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
3508         when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
3509                 .thenReturn(Arrays.asList(network));
3510         when(mClientModeImpl.syncGetPasspointConfigs(any())).thenReturn(Arrays.asList(config));
3511 
3512         mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
3513         mLooper.dispatchAll();
3514 
3515         verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, network.networkId);
3516         verify(mClientModeImpl).syncRemovePasspointConfig(mAsyncChannel, fqdn);
3517         verify(mWifiConfigManager).clearDeletedEphemeralNetworks();
3518         verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints();
3519         verify(mWifiNetworkSuggestionsManager).clear();
3520         verify(mWifiScoreCard).clear();
3521     }
3522 
3523     /**
3524      * Verify that Passpoint configuration is not removed in factoryReset if Passpoint feature
3525      * is not supported.
3526      */
3527     @Test
testFactoryResetWithoutPasspointSupport()3528     public void testFactoryResetWithoutPasspointSupport() throws Exception {
3529         setupClientModeImplHandlerForPost();
3530 
3531         mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
3532         when(mPackageManager.hasSystemFeature(
3533                 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false);
3534 
3535         mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
3536         mLooper.dispatchAll();
3537 
3538         verify(mClientModeImpl).syncGetConfiguredNetworks(anyInt(), any(), anyInt());
3539         verify(mClientModeImpl, never()).syncGetPasspointConfigs(any());
3540         verify(mClientModeImpl, never()).syncRemovePasspointConfig(any(), anyString());
3541         verify(mWifiConfigManager).clearDeletedEphemeralNetworks();
3542         verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints();
3543         verify(mWifiNetworkSuggestionsManager).clear();
3544     }
3545 
3546     /**
3547      * Verify that a call to factoryReset throws a SecurityException if the caller does not have
3548      * the CONNECTIVITY_INTERNAL permission.
3549      */
3550     @Test
testFactoryResetWithoutConnectivityInternalPermission()3551     public void testFactoryResetWithoutConnectivityInternalPermission() throws Exception {
3552         doThrow(new SecurityException()).when(mContext)
3553                 .enforceCallingOrSelfPermission(eq(Manifest.permission.CONNECTIVITY_INTERNAL),
3554                         eq("ConnectivityService"));
3555         mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
3556 
3557         try {
3558             mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
3559             fail();
3560         } catch (SecurityException e) {
3561         }
3562         verify(mClientModeImpl, never()).syncGetConfiguredNetworks(anyInt(), any(), anyInt());
3563         verify(mClientModeImpl, never()).syncGetPasspointConfigs(any());
3564     }
3565 
3566     /**
3567      * Verify that add or update networks is not allowed for apps targeting Q SDK.
3568      */
3569     @Test
testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSDK()3570     public void testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSDK() throws Exception {
3571         mLooper.dispatchAll();
3572         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3573                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3574         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3575 
3576         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3577         assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3578 
3579         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3580         verify(mClientModeImpl, never()).syncAddOrUpdateNetwork(any(), any());
3581         verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
3582     }
3583 
3584     /**
3585      * Verify that add or update networks is allowed for apps targeting below Q SDK.
3586      */
3587     @Test
testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSDK()3588     public void testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSDK() throws Exception {
3589         mLooper.dispatchAll();
3590         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3591                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3592         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3593         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
3594                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
3595 
3596         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3597         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3598 
3599         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3600         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3601         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3602     }
3603 
3604     /**
3605      * Verify that add or update networks is allowed for settings app.
3606      */
3607     @Test
testAddOrUpdateNetworkIsAllowedForSettingsApp()3608     public void testAddOrUpdateNetworkIsAllowedForSettingsApp() throws Exception {
3609         mLooper.dispatchAll();
3610         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3611                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3612         mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
3613         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3614 
3615         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3616         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3617 
3618         // Ensure that we don't check for change permission.
3619         verify(mContext, never()).enforceCallingOrSelfPermission(
3620                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
3621         verify(mAppOpsManager, never()).noteOp(
3622                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3623         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3624         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3625     }
3626 
3627     /**
3628      * Verify that add or update networks is allowed for system apps.
3629      */
3630     @Test
testAddOrUpdateNetworkIsAllowedForSystemApp()3631     public void testAddOrUpdateNetworkIsAllowedForSystemApp() throws Exception {
3632         mLooper.dispatchAll();
3633         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3634                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3635         mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
3636         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3637 
3638         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3639         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3640 
3641         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3642         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3643         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3644     }
3645 
3646     /**
3647      * Verify that add or update networks is allowed for apps holding system alert permission.
3648      */
3649     @Test
testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission()3650     public void testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission() throws Exception {
3651         mLooper.dispatchAll();
3652         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3653                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3654 
3655         when(mWifiPermissionsUtil.checkSystemAlertWindowPermission(
3656                 Process.myUid(), TEST_PACKAGE_NAME)).thenReturn(true);
3657         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3658 
3659         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3660         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3661 
3662         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3663         verify(mWifiPermissionsUtil).checkSystemAlertWindowPermission(anyInt(), anyString());
3664         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3665         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3666     }
3667 
3668     /**
3669      * Verify that add or update networks is allowed for DeviceOwner app.
3670      */
3671     @Test
testAddOrUpdateNetworkIsAllowedForDOApp()3672     public void testAddOrUpdateNetworkIsAllowedForDOApp() throws Exception {
3673         mLooper.dispatchAll();
3674         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3675                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3676         when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
3677                 Process.myUid(), DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
3678                 .thenReturn(true);
3679         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3680 
3681         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3682         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3683 
3684         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3685         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3686         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3687     }
3688 
3689     /**
3690      * Verify that add or update networks is allowed for ProfileOwner app.
3691      */
3692     @Test
testAddOrUpdateNetworkIsAllowedForPOApp()3693     public void testAddOrUpdateNetworkIsAllowedForPOApp() throws Exception {
3694         mLooper.dispatchAll();
3695         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3696                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3697         when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
3698                 Process.myUid(), DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
3699                 .thenReturn(true);
3700         when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
3701 
3702         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
3703         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
3704 
3705         verifyCheckChangePermission(TEST_PACKAGE_NAME);
3706         verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
3707         verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
3708     }
3709 
3710     /**
3711      * Verify that enableNetwork is allowed for privileged Apps
3712      */
3713     @Test
testEnableNetworkAllowedForPrivilegedApps()3714     public void testEnableNetworkAllowedForPrivilegedApps() throws Exception {
3715         mLooper.dispatchAll();
3716         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3717                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3718         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3719                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3720 
3721         mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
3722 
3723         verify(mClientModeImpl).syncEnableNetwork(eq(mAsyncChannel), eq(TEST_NETWORK_ID),
3724                 eq(true));
3725         verify(mWifiMetrics).incrementNumEnableNetworkCalls();
3726     }
3727 
3728     /**
3729      * Verify that enableNetwork is allowed for Apps targeting a SDK version less than Q
3730      */
3731     @Test
testEnabledNetworkAllowedForAppsTargetingLessThanQ()3732     public void testEnabledNetworkAllowedForAppsTargetingLessThanQ() throws Exception {
3733         mLooper.dispatchAll();
3734         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3735                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3736         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
3737                 eq(Build.VERSION_CODES.Q))).thenReturn(true);
3738 
3739         mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
3740 
3741         verify(mClientModeImpl).syncEnableNetwork(eq(mAsyncChannel), eq(TEST_NETWORK_ID),
3742                 eq(true));
3743         verify(mWifiMetrics).incrementNumEnableNetworkCalls();
3744     }
3745 
3746     /**
3747      * Verify that enableNetwork is not allowed for Apps targeting Q SDK
3748      */
3749     @Test
testEnableNetworkNotAllowedForAppsTargetingQ()3750     public void testEnableNetworkNotAllowedForAppsTargetingQ() throws Exception {
3751         mLooper.dispatchAll();
3752         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
3753                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
3754 
3755         mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
3756 
3757         verify(mClientModeImpl, never()).syncEnableNetwork(anyObject(), anyInt(), anyBoolean());
3758         verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
3759     }
3760 
3761     /**
3762      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to add network
3763      * suggestions.
3764      */
3765     @Test
testAddNetworkSuggestions()3766     public void testAddNetworkSuggestions() {
3767         setupClientModeImplHandlerForRunWithScissors();
3768 
3769         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString()))
3770                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
3771         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
3772                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3773 
3774         when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString()))
3775                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE);
3776         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
3777                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3778 
3779         doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
3780                 .runWithScissors(any(), anyLong());
3781         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
3782                 mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3783 
3784         verify(mWifiNetworkSuggestionsManager, times(2)).add(
3785                 any(), eq(Binder.getCallingUid()),  eq(TEST_PACKAGE_NAME));
3786     }
3787 
3788     /**
3789      * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to remove network
3790      * suggestions.
3791      */
3792     @Test
testRemoveNetworkSuggestions()3793     public void testRemoveNetworkSuggestions() {
3794         setupClientModeImplHandlerForRunWithScissors();
3795 
3796         when(mWifiNetworkSuggestionsManager.remove(any(), anyString()))
3797                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID);
3798         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
3799                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3800 
3801         when(mWifiNetworkSuggestionsManager.remove(any(), anyString()))
3802                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
3803         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
3804                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3805 
3806         doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
3807                 .runWithScissors(any(), anyLong());
3808         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
3809                 mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
3810 
3811         verify(mWifiNetworkSuggestionsManager, times(2)).remove(any(), eq(TEST_PACKAGE_NAME));
3812     }
3813 
3814     /**
3815      * Verify that if the caller has NETWORK_SETTINGS permission, then it can invoke
3816      * {@link WifiManager#disableEphemeralNetwork(String)}.
3817      */
3818     @Test
testDisableEphemeralNetworkWithNetworkSettingsPerm()3819     public void testDisableEphemeralNetworkWithNetworkSettingsPerm() throws Exception {
3820         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3821                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
3822         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
3823         verify(mClientModeImpl).disableEphemeralNetwork(anyString());
3824     }
3825 
3826     /**
3827      * Verify that if the caller does not have NETWORK_SETTINGS permission, then it cannot invoke
3828      * {@link WifiManager#disableEphemeralNetwork(String)}.
3829      */
3830     @Test
testDisableEphemeralNetworkWithoutNetworkSettingsPerm()3831     public void testDisableEphemeralNetworkWithoutNetworkSettingsPerm() throws Exception {
3832         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
3833                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
3834         mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
3835         verify(mClientModeImpl, never()).disableEphemeralNetwork(anyString());
3836     }
3837 
3838     /**
3839      * Verify getting the factory MAC address.
3840      */
3841     @Test
testGetFactoryMacAddresses()3842     public void testGetFactoryMacAddresses() throws Exception {
3843         setupClientModeImplHandlerForRunWithScissors();
3844         when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
3845         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
3846         final String[] factoryMacs = mWifiServiceImpl.getFactoryMacAddresses();
3847         assertEquals(1, factoryMacs.length);
3848         assertEquals(TEST_FACTORY_MAC, factoryMacs[0]);
3849         verify(mClientModeImpl).getFactoryMacAddress();
3850     }
3851 
3852     /**
3853      * Verify getting the factory MAC address returns null when posting the runnable to handler
3854      * fails.
3855      */
3856     @Test
testGetFactoryMacAddressesPostFail()3857     public void testGetFactoryMacAddressesPostFail() throws Exception {
3858         setupClientModeImplHandlerForRunWithScissors();
3859         doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
3860                 .runWithScissors(any(), anyLong());
3861         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
3862         assertNull(mWifiServiceImpl.getFactoryMacAddresses());
3863         verify(mClientModeImpl, never()).getFactoryMacAddress();
3864     }
3865 
3866     /**
3867      * Verify getting the factory MAC address returns null when the lower layers fail.
3868      */
3869     @Test
testGetFactoryMacAddressesFail()3870     public void testGetFactoryMacAddressesFail() throws Exception {
3871         setupClientModeImplHandlerForRunWithScissors();
3872         when(mClientModeImpl.getFactoryMacAddress()).thenReturn(null);
3873         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
3874         assertNull(mWifiServiceImpl.getFactoryMacAddresses());
3875         verify(mClientModeImpl).getFactoryMacAddress();
3876     }
3877 
3878     /**
3879      * Verify getting the factory MAC address throws a SecurityException if the calling app
3880      * doesn't have NETWORK_SETTINGS permission.
3881      */
3882     @Test
testGetFactoryMacAddressesFailNoNetworkSettingsPermission()3883     public void testGetFactoryMacAddressesFailNoNetworkSettingsPermission() throws Exception {
3884         setupClientModeImplHandlerForRunWithScissors();
3885         when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
3886         when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
3887         try {
3888             mWifiServiceImpl.getFactoryMacAddresses();
3889             fail();
3890         } catch (SecurityException e) {
3891             assertTrue("Exception message should contain 'factory MAC'",
3892                     e.toString().contains("factory MAC"));
3893         }
3894     }
3895 
3896     /**
3897      * Verify that a call to setDeviceMobilityState throws a SecurityException if the
3898      * caller does not have WIFI_SET_DEVICE_MOBILITY_STATE permission.
3899      */
3900     @Test
setDeviceMobilityStateThrowsSecurityExceptionOnMissingPermissions()3901     public void setDeviceMobilityStateThrowsSecurityExceptionOnMissingPermissions() {
3902         doThrow(new SecurityException()).when(mContext)
3903                 .enforceCallingPermission(
3904                         eq(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE),
3905                         eq("WifiService"));
3906         try {
3907             mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
3908             fail("expected SecurityException");
3909         } catch (SecurityException expected) {
3910         }
3911     }
3912 
3913     /**
3914      * Verifies that setDeviceMobilityState runs on a separate handler thread.
3915      */
3916     @Test
setDeviceMobilityStateRunsOnHandler()3917     public void setDeviceMobilityStateRunsOnHandler() {
3918         setupClientModeImplHandlerForPost();
3919 
3920         mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
3921         verify(mClientModeImpl, never()).setDeviceMobilityState(anyInt());
3922         mLooper.dispatchAll();
3923         verify(mClientModeImpl).setDeviceMobilityState(eq(DEVICE_MOBILITY_STATE_STATIONARY));
3924     }
3925 
3926     /**
3927      * Verify that a call to addOnWifiUsabilityStatsListener throws a SecurityException if
3928      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
3929      */
3930     @Test
testAddStatsListenerThrowsSecurityExceptionOnMissingPermissions()3931     public void testAddStatsListenerThrowsSecurityExceptionOnMissingPermissions() {
3932         doThrow(new SecurityException()).when(mContext)
3933                 .enforceCallingPermission(
3934                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
3935                         eq("WifiService"));
3936         try {
3937             mWifiServiceImpl.addOnWifiUsabilityStatsListener(mAppBinder,
3938                     mOnWifiUsabilityStatsListener, TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
3939             fail("expected SecurityException");
3940         } catch (SecurityException expected) {
3941         }
3942     }
3943 
3944     /**
3945      * Verify that a call to addOnWifiUsabilityStatsListener throws an IllegalArgumentException
3946      * if the parameters are not provided.
3947      */
3948     @Test
testAddStatsListenerThrowsIllegalArgumentExceptionOnInvalidArguments()3949     public void testAddStatsListenerThrowsIllegalArgumentExceptionOnInvalidArguments() {
3950         try {
3951             mWifiServiceImpl.addOnWifiUsabilityStatsListener(
3952                     mAppBinder, null, TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
3953             fail("expected IllegalArgumentException");
3954         } catch (IllegalArgumentException expected) {
3955         }
3956     }
3957 
3958     /**
3959      * Verify that a call to removeOnWifiUsabilityStatsListener throws a SecurityException if
3960      * the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
3961      */
3962     @Test
testRemoveStatsListenerThrowsSecurityExceptionOnMissingPermissions()3963     public void testRemoveStatsListenerThrowsSecurityExceptionOnMissingPermissions() {
3964         doThrow(new SecurityException()).when(mContext)
3965                 .enforceCallingPermission(
3966                         eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
3967                         eq("WifiService"));
3968         try {
3969             mWifiServiceImpl.removeOnWifiUsabilityStatsListener(
3970                     TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
3971             fail("expected SecurityException");
3972         } catch (SecurityException expected) {
3973         }
3974     }
3975 
3976     /**
3977      * Verify that addOnWifiUsabilityStatsListener adds listener to {@link WifiMetrics}.
3978      */
3979     @Test
testAddOnWifiUsabilityStatsListenerAndVerify()3980     public void testAddOnWifiUsabilityStatsListenerAndVerify() throws Exception {
3981         setupClientModeImplHandlerForPost();
3982 
3983         mWifiServiceImpl.addOnWifiUsabilityStatsListener(mAppBinder, mOnWifiUsabilityStatsListener,
3984                 TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
3985         mLooper.dispatchAll();
3986         verify(mWifiMetrics).addOnWifiUsabilityListener(mAppBinder, mOnWifiUsabilityStatsListener,
3987                 TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
3988     }
3989 
3990     /**
3991      * Verify that removeOnWifiUsabilityStatsListener removes listener from
3992      * {@link WifiMetrics}.
3993      */
3994     @Test
testRemoveOnWifiUsabilityStatsListenerAndVerify()3995     public void testRemoveOnWifiUsabilityStatsListenerAndVerify() throws Exception {
3996         setupClientModeImplHandlerForPost();
3997 
3998         mWifiServiceImpl.removeOnWifiUsabilityStatsListener(0);
3999         mLooper.dispatchAll();
4000         verify(mWifiMetrics).removeOnWifiUsabilityListener(0);
4001     }
4002 
4003     /**
4004      * Verify that a call to updateWifiUsabilityScore throws a SecurityException if the
4005      * caller does not have UPDATE_WIFI_USABILITY_SCORE permission.
4006      */
4007     @Test
testUpdateWifiUsabilityScoreThrowsSecurityExceptionOnMissingPermissions()4008     public void testUpdateWifiUsabilityScoreThrowsSecurityExceptionOnMissingPermissions() {
4009         doThrow(new SecurityException()).when(mContext)
4010                 .enforceCallingPermission(
4011                 eq(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE),
4012                 eq("WifiService"));
4013         try {
4014             mWifiServiceImpl.updateWifiUsabilityScore(anyInt(), anyInt(), 15);
4015             fail("expected SecurityException");
4016         } catch (SecurityException expected) {
4017         }
4018     }
4019 
4020     /**
4021      * Verify that mClientModeImpl in WifiServiceImpl is being updated on Wifi usability score
4022      * update event.
4023      */
4024     @Test
testWifiUsabilityScoreUpdateAfterScoreEvent()4025     public void testWifiUsabilityScoreUpdateAfterScoreEvent() {
4026         setupClientModeImplHandlerForPost();
4027 
4028         mWifiServiceImpl.updateWifiUsabilityScore(anyInt(), anyInt(), 15);
4029         mLooper.dispatchAll();
4030         verify(mClientModeImpl).updateWifiUsabilityScore(anyInt(), anyInt(), anyInt());
4031     }
4032 
setupMaxApInterfaces(int val)4033     private void setupMaxApInterfaces(int val) {
4034         when(mResources.getInteger(
4035                 eq(com.android.internal.R.integer.config_wifi_max_ap_interfaces)))
4036                 .thenReturn(val);
4037     }
4038 
startLohsAndTethering(int apCount)4039     private void startLohsAndTethering(int apCount) {
4040         // initialization
4041         setupClientModeImplHandlerForPost();
4042         setupMaxApInterfaces(apCount);
4043         mWifiServiceImpl.checkAndStartWifi();
4044         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
4045                 (IntentFilter) argThat(new IntentFilterMatcher()));
4046 
4047         // start LOHS
4048         registerLOHSRequestFull();
4049         String ifaceName = apCount >= 2 ? WIFI_IFACE_NAME2 : WIFI_IFACE_NAME;
4050         mWifiServiceImpl.updateInterfaceIpState(ifaceName, IFACE_IP_MODE_LOCAL_ONLY);
4051         mLooper.dispatchAll();
4052         verify(mWifiController)
4053                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
4054         verify(mHandler).handleMessage(mMessageCaptor.capture());
4055         assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what);
4056         reset(mWifiController);
4057         reset(mHandler);
4058 
4059         // start tethering
4060         boolean tetheringResult = mWifiServiceImpl.startSoftAp(null);
4061         assertTrue(tetheringResult);
4062         verify(mWifiController)
4063                 .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
4064         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
4065         mLooper.dispatchAll();
4066     }
4067 
4068     /**
4069      * Verify LOHS gets stopped when trying to start tethering concurrently on devices that
4070      * doesn't support dual AP operation.
4071      */
4072     @Test
testStartLohsAndTethering1AP()4073     public void testStartLohsAndTethering1AP() {
4074         startLohsAndTethering(1);
4075 
4076         // verify LOHS got stopped
4077         mLooper.dispatchAll();
4078         verify(mHandler).handleMessage(mMessageCaptor.capture());
4079         assertEquals(HOTSPOT_FAILED, mMessageCaptor.getValue().what);
4080         verify(mWifiController)
4081                 .sendMessage(eq(CMD_SET_AP), eq(0), eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
4082     }
4083 
4084     /**
4085      * Verify LOHS doesn't get stopped when trying to start tethering concurrently on devices
4086      * that does support dual AP operation.
4087      */
4088     @Test
testStartLohsAndTethering2AP()4089     public void testStartLohsAndTethering2AP() {
4090         startLohsAndTethering(2);
4091 
4092         // verify LOHS didn't get stopped
4093         mLooper.dispatchAll();
4094         verify(mHandler, never()).handleMessage(any(Message.class));
4095         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), anyInt());
4096     }
4097 
4098     /**
4099      * Verify that the call to startDppAsConfiguratorInitiator throws a security exception when the
4100      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
4101      */
4102     @Test(expected = SecurityException.class)
testStartDppAsConfiguratorInitiatorWithoutPermissions()4103     public void testStartDppAsConfiguratorInitiatorWithoutPermissions() {
4104         mWifiServiceImpl.startDppAsConfiguratorInitiator(mAppBinder, DPP_URI,
4105                 1, 1, mDppCallback);
4106     }
4107 
4108     /**
4109      * Verify that the call to startDppAsEnrolleeInitiator throws a security exception when the
4110      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
4111      */
4112     @Test(expected = SecurityException.class)
testStartDppAsEnrolleeInitiatorWithoutPermissions()4113     public void testStartDppAsEnrolleeInitiatorWithoutPermissions() {
4114         mWifiServiceImpl.startDppAsEnrolleeInitiator(mAppBinder, DPP_URI, mDppCallback);
4115     }
4116 
4117     /**
4118      * Verify that the call to stopDppSession throws a security exception when the
4119      * caller doesn't have NETWORK_SETTINGS permissions or NETWORK_SETUP_WIZARD.
4120      */
4121     @Test(expected = SecurityException.class)
testStopDppSessionWithoutPermissions()4122     public void testStopDppSessionWithoutPermissions() {
4123         try {
4124             mWifiServiceImpl.stopDppSession();
4125         } catch (RemoteException e) {
4126         }
4127     }
4128 }
4129