• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2016 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.android.server.wifi;
18  
19  import static android.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