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.HOTSPOT_FAILED; 20 import static android.net.wifi.WifiManager.HOTSPOT_STARTED; 21 import static android.net.wifi.WifiManager.HOTSPOT_STOPPED; 22 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR; 23 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 24 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 25 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; 26 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; 27 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; 28 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED; 29 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; 30 import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL; 31 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 32 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; 33 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 34 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; 35 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 36 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; 37 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; 38 import static android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 39 import static android.provider.Settings.Secure.LOCATION_MODE_OFF; 40 41 import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR; 42 import static com.android.server.wifi.WifiController.CMD_SET_AP; 43 import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED; 44 45 import static org.junit.Assert.assertEquals; 46 import static org.junit.Assert.assertFalse; 47 import static org.junit.Assert.assertNotNull; 48 import static org.junit.Assert.assertNull; 49 import static org.junit.Assert.assertTrue; 50 import static org.junit.Assert.fail; 51 import static org.mockito.Matchers.any; 52 import static org.mockito.Matchers.anyString; 53 import static org.mockito.Matchers.eq; 54 import static org.mockito.Mockito.*; 55 import static org.mockito.Mockito.atLeastOnce; 56 57 import android.app.ActivityManager; 58 import android.app.AppOpsManager; 59 import android.content.BroadcastReceiver; 60 import android.content.ContentResolver; 61 import android.content.Context; 62 import android.content.Intent; 63 import android.content.IntentFilter; 64 import android.content.pm.ApplicationInfo; 65 import android.content.pm.PackageManager; 66 import android.content.res.Resources; 67 import android.net.Uri; 68 import android.net.wifi.ISoftApCallback; 69 import android.net.wifi.ScanResult; 70 import android.net.wifi.WifiConfiguration; 71 import android.net.wifi.WifiConfiguration.KeyMgmt; 72 import android.net.wifi.WifiEnterpriseConfig; 73 import android.net.wifi.WifiInfo; 74 import android.net.wifi.WifiManager; 75 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback; 76 import android.net.wifi.WifiManager.SoftApCallback; 77 import android.net.wifi.WifiSsid; 78 import android.net.wifi.hotspot2.IProvisioningCallback; 79 import android.net.wifi.hotspot2.OsuProvider; 80 import android.net.wifi.hotspot2.PasspointConfiguration; 81 import android.os.Binder; 82 import android.os.Handler; 83 import android.os.HandlerThread; 84 import android.os.IBinder; 85 import android.os.IPowerManager; 86 import android.os.Looper; 87 import android.os.Message; 88 import android.os.Messenger; 89 import android.os.PowerManager; 90 import android.os.Process; 91 import android.os.RemoteException; 92 import android.os.UserManager; 93 import android.os.test.TestLooper; 94 import android.support.test.filters.SmallTest; 95 96 import com.android.internal.os.PowerProfile; 97 import com.android.internal.telephony.TelephonyIntents; 98 import com.android.internal.util.AsyncChannel; 99 import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback; 100 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil; 101 import com.android.server.wifi.util.WifiAsyncChannel; 102 import com.android.server.wifi.util.WifiPermissionsUtil; 103 import com.android.server.wifi.util.WifiPermissionsWrapper; 104 105 import org.junit.Before; 106 import org.junit.Ignore; 107 import org.junit.Test; 108 import org.mockito.ArgumentCaptor; 109 import org.mockito.ArgumentMatcher; 110 import org.mockito.Mock; 111 import org.mockito.MockitoAnnotations; 112 import org.mockito.Spy; 113 114 import java.io.FileDescriptor; 115 import java.io.PrintWriter; 116 import java.io.StringWriter; 117 import java.util.ArrayList; 118 import java.util.Arrays; 119 import java.util.List; 120 121 /** 122 * Unit tests for {@link WifiServiceImpl}. 123 * 124 * Note: this is intended to build up over time and will not immediately cover the entire file. 125 */ 126 @SmallTest 127 public class WifiServiceImplTest { 128 129 private static final String TAG = "WifiServiceImplTest"; 130 private static final String SCAN_PACKAGE_NAME = "scanPackage"; 131 private static final int DEFAULT_VERBOSE_LOGGING = 0; 132 private static final String ANDROID_SYSTEM_PACKAGE = "android"; 133 private static final String TEST_PACKAGE_NAME = "TestPackage"; 134 private static final String SYSUI_PACKAGE_NAME = "com.android.systemui"; 135 private static final int TEST_PID = 6789; 136 private static final int TEST_PID2 = 9876; 137 private static final int TEST_UID = 1200000; 138 private static final int OTHER_TEST_UID = 1300000; 139 private static final int TEST_USER_HANDLE = 13; 140 private static final String WIFI_IFACE_NAME = "wlan0"; 141 private static final String TEST_COUNTRY_CODE = "US"; 142 143 private WifiServiceImpl mWifiServiceImpl; 144 private TestLooper mLooper; 145 private PowerManager mPowerManager; 146 private Handler mHandler; 147 private Handler mHandlerSpyForWsmRunWithScissors; 148 private Messenger mAppMessenger; 149 private int mPid; 150 private int mPid2 = Process.myPid(); 151 private OsuProvider mOsuProvider; 152 private SoftApCallback mStateMachineSoftApCallback; 153 154 final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = 155 ArgumentCaptor.forClass(BroadcastReceiver.class); 156 final ArgumentCaptor<IntentFilter> mIntentFilterCaptor = 157 ArgumentCaptor.forClass(IntentFilter.class); 158 159 final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class); 160 final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor = 161 ArgumentCaptor.forClass(SoftApModeConfiguration.class); 162 163 @Mock Context mContext; 164 @Mock WifiInjector mWifiInjector; 165 @Mock WifiCountryCode mWifiCountryCode; 166 @Mock Clock mClock; 167 @Mock WifiController mWifiController; 168 @Mock WifiTrafficPoller mWifiTrafficPoller; 169 @Mock WifiStateMachine mWifiStateMachine; 170 @Mock WifiStateMachinePrime mWifiStateMachinePrime; 171 @Mock HandlerThread mHandlerThread; 172 @Mock AsyncChannel mAsyncChannel; 173 @Mock Resources mResources; 174 @Mock ApplicationInfo mApplicationInfo; 175 @Mock FrameworkFacade mFrameworkFacade; 176 @Mock WifiLockManager mLockManager; 177 @Mock WifiMulticastLockManager mWifiMulticastLockManager; 178 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 179 @Mock WifiBackupRestore mWifiBackupRestore; 180 @Mock WifiMetrics mWifiMetrics; 181 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 182 @Mock WifiPermissionsWrapper mWifiPermissionsWrapper; 183 @Mock WifiSettingsStore mSettingsStore; 184 @Mock ContentResolver mContentResolver; 185 @Mock PackageManager mPackageManager; 186 @Mock UserManager mUserManager; 187 @Mock WifiApConfigStore mWifiApConfigStore; 188 @Mock WifiConfiguration mApConfig; 189 @Mock ActivityManager mActivityManager; 190 @Mock AppOpsManager mAppOpsManager; 191 @Mock IBinder mAppBinder; 192 @Mock LocalOnlyHotspotRequestInfo mRequestInfo; 193 @Mock LocalOnlyHotspotRequestInfo mRequestInfo2; 194 @Mock IProvisioningCallback mProvisioningCallback; 195 @Mock ISoftApCallback mClientSoftApCallback; 196 @Mock ISoftApCallback mAnotherSoftApCallback; 197 @Mock PowerProfile mPowerProfile; 198 @Mock WifiTrafficPoller mWifiTrafficPolller; 199 @Mock ScanRequestProxy mScanRequestProxy; 200 201 @Spy FakeWifiLog mLog; 202 203 private class WifiAsyncChannelTester { 204 private static final String TAG = "WifiAsyncChannelTester"; 205 public static final int CHANNEL_STATE_FAILURE = -1; 206 public static final int CHANNEL_STATE_DISCONNECTED = 0; 207 public static final int CHANNEL_STATE_HALF_CONNECTED = 1; 208 public static final int CHANNEL_STATE_FULLY_CONNECTED = 2; 209 210 private int mState = CHANNEL_STATE_DISCONNECTED; 211 private WifiAsyncChannel mChannel; 212 private WifiLog mAsyncTestLog; 213 214 WifiAsyncChannelTester(WifiInjector wifiInjector) { 215 mAsyncTestLog = wifiInjector.makeLog(TAG); 216 } 217 218 public int getChannelState() { 219 return mState; 220 } 221 222 public void connect(final Looper looper, final Messenger messenger, 223 final Handler incomingMessageHandler) { 224 assertEquals("AsyncChannel must be in disconnected state", 225 CHANNEL_STATE_DISCONNECTED, mState); 226 mChannel = new WifiAsyncChannel(TAG); 227 mChannel.setWifiLog(mLog); 228 Handler handler = new Handler(mLooper.getLooper()) { 229 @Override 230 public void handleMessage(Message msg) { 231 switch (msg.what) { 232 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 233 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 234 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 235 mState = CHANNEL_STATE_HALF_CONNECTED; 236 } else { 237 mState = CHANNEL_STATE_FAILURE; 238 } 239 break; 240 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 241 mState = CHANNEL_STATE_FULLY_CONNECTED; 242 break; 243 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 244 mState = CHANNEL_STATE_DISCONNECTED; 245 break; 246 default: 247 incomingMessageHandler.handleMessage(msg); 248 break; 249 } 250 } 251 }; 252 mChannel.connect(null, handler, messenger); 253 } 254 255 private Message sendMessageSynchronously(Message request) { 256 return mChannel.sendMessageSynchronously(request); 257 } 258 259 private void sendMessage(Message request) { 260 mChannel.sendMessage(request); 261 } 262 } 263 264 @Before public void setUp() { 265 MockitoAnnotations.initMocks(this); 266 mLooper = new TestLooper(); 267 mHandler = spy(new Handler(mLooper.getLooper())); 268 mAppMessenger = new Messenger(mHandler); 269 270 when(mRequestInfo.getPid()).thenReturn(mPid); 271 when(mRequestInfo2.getPid()).thenReturn(mPid2); 272 when(mWifiInjector.getUserManager()).thenReturn(mUserManager); 273 when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode); 274 when(mWifiInjector.getWifiController()).thenReturn(mWifiController); 275 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 276 when(mWifiInjector.getWifiStateMachine()).thenReturn(mWifiStateMachine); 277 when(mWifiStateMachine.syncInitialize(any())).thenReturn(true); 278 when(mWifiInjector.getWifiStateMachinePrime()).thenReturn(mWifiStateMachinePrime); 279 when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread); 280 when(mWifiInjector.getPowerProfile()).thenReturn(mPowerProfile); 281 when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper()); 282 when(mContext.getResources()).thenReturn(mResources); 283 when(mContext.getContentResolver()).thenReturn(mContentResolver); 284 when(mContext.getPackageManager()).thenReturn(mPackageManager); 285 when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore); 286 doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(), 287 anyBoolean(), any()); 288 when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager); 289 when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); 290 IPowerManager powerManagerService = mock(IPowerManager.class); 291 mPowerManager = new PowerManager(mContext, powerManagerService, new Handler()); 292 when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE); 293 when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager); 294 WifiAsyncChannel wifiAsyncChannel = new WifiAsyncChannel("WifiServiceImplTest"); 295 wifiAsyncChannel.setWifiLog(mLog); 296 when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(wifiAsyncChannel); 297 when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade); 298 when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager); 299 when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager); 300 when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog); 301 when(mWifiInjector.getWifiBackupRestore()).thenReturn(mWifiBackupRestore); 302 when(mWifiInjector.makeLog(anyString())).thenReturn(mLog); 303 when(mWifiInjector.getWifiTrafficPoller()).thenReturn(mWifiTrafficPoller); 304 when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil); 305 when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper); 306 when(mWifiInjector.getWifiSettingsStore()).thenReturn(mSettingsStore); 307 when(mWifiInjector.getClock()).thenReturn(mClock); 308 when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy); 309 when(mWifiStateMachine.syncStartSubscriptionProvisioning(anyInt(), 310 any(OsuProvider.class), any(IProvisioningCallback.class), any())).thenReturn(true); 311 when(mPackageManager.hasSystemFeature( 312 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true); 313 // Create an OSU provider that can be provisioned via an open OSU AP 314 mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 315 when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); 316 when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 317 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED); 318 when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true); 319 320 ArgumentCaptor<SoftApCallback> softApCallbackCaptor = 321 ArgumentCaptor.forClass(SoftApCallback.class); 322 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 323 verify(mWifiStateMachinePrime).registerSoftApCallback(softApCallbackCaptor.capture()); 324 mStateMachineSoftApCallback = softApCallbackCaptor.getValue(); 325 mWifiServiceImpl.setWifiHandlerLogForTest(mLog); 326 } 327 328 private WifiAsyncChannelTester verifyAsyncChannelHalfConnected() throws RemoteException { 329 WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector); 330 Handler handler = mock(Handler.class); 331 TestLooper looper = new TestLooper(); 332 channelTester.connect(looper.getLooper(), 333 mWifiServiceImpl.getWifiServiceMessenger(TEST_PACKAGE_NAME), handler); 334 mLooper.dispatchAll(); 335 assertEquals("AsyncChannel must be half connected", 336 WifiAsyncChannelTester.CHANNEL_STATE_HALF_CONNECTED, 337 channelTester.getChannelState()); 338 return channelTester; 339 } 340 341 /** 342 * Verifies that any operations on WifiServiceImpl without setting up the WifiStateMachine 343 * channel would fail. 344 */ 345 @Test 346 public void testRemoveNetworkUnknown() { 347 assertFalse(mWifiServiceImpl.removeNetwork(-1, TEST_PACKAGE_NAME)); 348 verify(mWifiStateMachine, never()).syncRemoveNetwork(any(), anyInt()); 349 } 350 351 /** 352 * Tests whether we're able to set up an async channel connection with WifiServiceImpl. 353 * This is the path used by some WifiManager public API calls. 354 */ 355 @Test 356 public void testAsyncChannelHalfConnected() throws RemoteException { 357 verifyAsyncChannelHalfConnected(); 358 } 359 360 /** 361 * Ensure WifiMetrics.dump() is the only dump called when 'dumpsys wifi WifiMetricsProto' is 362 * called. This is required to support simple metrics collection via dumpsys 363 */ 364 @Test 365 public void testWifiMetricsDump() { 366 mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), 367 new String[]{mWifiMetrics.PROTO_DUMP_ARG}); 368 verify(mWifiMetrics) 369 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class)); 370 verify(mWifiStateMachine, never()) 371 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class)); 372 } 373 374 /** 375 * Ensure WifiServiceImpl.dump() doesn't throw an NPE when executed with null args 376 */ 377 @Test 378 public void testDumpNullArgs() { 379 mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); 380 } 381 382 /** 383 * Verify that wifi can be enabled by a caller with WIFI_STATE_CHANGE permission when wifi is 384 * off (no hotspot, no airplane mode). 385 * 386 * Note: hotspot is disabled by default 387 */ 388 @Test 389 public void testSetWifiEnabledSuccess() throws Exception { 390 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 391 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 392 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 393 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 394 } 395 396 /** 397 * Verify that the CMD_TOGGLE_WIFI message won't be sent if wifi is already on. 398 */ 399 @Test 400 public void testSetWifiEnabledNoToggle() throws Exception { 401 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(false); 402 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 403 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 404 } 405 406 /** 407 * Verify a SecurityException is thrown if a caller does not have the correct permission to 408 * toggle wifi. 409 */ 410 @Test 411 public void testSetWifiEnableWithoutPermission() throws Exception { 412 doThrow(new SecurityException()).when(mContext) 413 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 414 eq("WifiService")); 415 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 416 try { 417 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); 418 fail(); 419 } catch (SecurityException e) { 420 421 } 422 423 } 424 425 /** 426 * Verify a SecurityException is thrown if OPSTR_CHANGE_WIFI_STATE is disabled for the app. 427 */ 428 @Test 429 public void testSetWifiEnableAppOpsRejected() throws Exception { 430 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 431 doThrow(new SecurityException()).when(mAppOpsManager) 432 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME); 433 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 434 try { 435 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); 436 fail(); 437 } catch (SecurityException e) { 438 439 } 440 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 441 } 442 443 /** 444 * Verify a SecurityException is thrown if OP_CHANGE_WIFI_STATE is set to MODE_IGNORED 445 * for the app. 446 */ 447 @Test // No exception expected, but the operation should not be done 448 public void testSetWifiEnableAppOpsIgnored() throws Exception { 449 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 450 doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager) 451 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME); 452 453 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 454 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); 455 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 456 } 457 458 /** 459 * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we 460 * are in airplane mode. 461 */ 462 @Test 463 public void testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode() throws Exception { 464 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 465 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 466 when(mContext.checkPermission( 467 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())) 468 .thenReturn(PackageManager.PERMISSION_GRANTED); 469 assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true)); 470 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 471 } 472 473 /** 474 * Verify that a caller without the NETWORK_SETTINGS permission can't enable wifi 475 * if we are in airplane mode. 476 */ 477 @Test 478 public void testSetWifiEnabledFromAppFailsWhenInAirplaneMode() throws Exception { 479 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 480 when(mSettingsStore.isAirplaneModeOn()).thenReturn(true); 481 when(mContext.checkPermission( 482 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())) 483 .thenReturn(PackageManager.PERMISSION_DENIED); 484 assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 485 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 486 } 487 488 /** 489 * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we 490 * are in softap mode. 491 */ 492 @Test 493 public void testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled() throws Exception { 494 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 495 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 496 mWifiServiceImpl.checkAndStartWifi(); 497 498 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 499 (IntentFilter) argThat(new IntentFilterMatcher())); 500 501 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 502 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL, 503 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 504 505 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 506 when(mContext.checkPermission( 507 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())) 508 .thenReturn(PackageManager.PERMISSION_GRANTED); 509 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 510 assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true)); 511 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 512 } 513 514 /** 515 * Verify that a call from an app cannot enable wifi if we are in softap mode. 516 */ 517 @Test 518 public void testSetWifiEnabledFromAppFailsWhenApEnabled() throws Exception { 519 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 520 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 521 mWifiServiceImpl.checkAndStartWifi(); 522 523 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 524 (IntentFilter) argThat(new IntentFilterMatcher())); 525 526 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 527 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL, 528 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 529 530 when(mContext.checkPermission( 531 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt())) 532 .thenReturn(PackageManager.PERMISSION_DENIED); 533 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 534 assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 535 verify(mSettingsStore, never()).handleWifiToggled(anyBoolean()); 536 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 537 } 538 539 /** 540 * Verify that wifi can be enabled without consent UI popup when permission 541 * review is required but got permission granted. 542 */ 543 @Test 544 public void testSetWifiEnabledSuccessWhenPermissionReviewRequiredAndPermissionGranted() 545 throws Exception { 546 // Set PermissionReviewRequired to true explicitly 547 when(mResources.getBoolean(anyInt())).thenReturn(true); 548 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 549 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 550 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 551 when(mContext.checkCallingPermission( 552 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 553 .thenReturn(PackageManager.PERMISSION_GRANTED); 554 555 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 556 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 557 } 558 559 /** 560 * Verify that wifi is not enabled but got consent UI popup when permission 561 * review is required but do not have permission. 562 */ 563 @Test 564 public void testSetWifiEnabledConsentUiWhenPermissionReviewRequiredAndPermissionDenied() 565 throws Exception { 566 // Set PermissionReviewRequired to true explicitly 567 when(mResources.getBoolean(anyInt())).thenReturn(true); 568 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 569 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 570 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 571 when(mContext.checkCallingPermission( 572 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 573 .thenReturn(PackageManager.PERMISSION_DENIED); 574 when(mPackageManager.getApplicationInfoAsUser( 575 anyString(), anyInt(), anyInt())) 576 .thenReturn(mApplicationInfo); 577 mApplicationInfo.uid = TEST_UID; 578 int uid = Binder.getCallingUid(); 579 BinderUtil.setUid(TEST_UID); 580 581 try { 582 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 583 } finally { 584 BinderUtil.setUid(uid); 585 } 586 587 verify(mContext).startActivity(any()); 588 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 589 } 590 591 /** 592 * Verify that wifi can be enabled when wifi is off and permission review is 593 * not required. 594 */ 595 @Test 596 public void testSetWifiEnabledSuccessWhenPermissionReviewNotRequired() throws Exception { 597 // Set PermissionReviewRequired to false explicitly 598 when(mResources.getBoolean(anyInt())).thenReturn(false); 599 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 600 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 601 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 602 603 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 604 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 605 } 606 607 /** 608 * Verify a SecurityException is thrown when bringing up Consent UI but caller 609 * uid does not match application uid. 610 * 611 * @throws SecurityException 612 */ 613 @Test 614 public void testSetWifiEnabledThrowsSecurityExceptionForConsentUiIfUidNotMatch() 615 throws Exception { 616 // Set PermissionReviewRequired to true explicitly 617 when(mResources.getBoolean(anyInt())).thenReturn(true); 618 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 619 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 620 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 621 when(mContext.checkCallingPermission( 622 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 623 .thenReturn(PackageManager.PERMISSION_DENIED); 624 when(mPackageManager.getApplicationInfoAsUser( 625 anyString(), anyInt(), anyInt())) 626 .thenReturn(mApplicationInfo); 627 mApplicationInfo.uid = TEST_UID; 628 int uid = Binder.getCallingUid(); 629 BinderUtil.setUid(OTHER_TEST_UID); 630 631 try { 632 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); 633 fail(); 634 } catch (SecurityException e) { 635 } finally { 636 BinderUtil.setUid(uid); 637 } 638 } 639 640 /** 641 * Verify that wifi can be disabled by a caller with WIFI_STATE_CHANGE permission when wifi is 642 * on. 643 */ 644 @Test 645 public void testSetWifiDisabledSuccess() throws Exception { 646 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 647 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 648 verifyCheckChangePermission(TEST_PACKAGE_NAME); 649 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 650 } 651 652 /** 653 * Verify that CMD_TOGGLE_WIFI message won't be sent if wifi is already off. 654 */ 655 @Test 656 public void testSetWifiDisabledNoToggle() throws Exception { 657 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false); 658 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 659 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 660 } 661 662 /** 663 * Verify a SecurityException is thrown if a caller does not have the correct permission to 664 * toggle wifi. 665 */ 666 @Test 667 public void testSetWifiDisabledWithoutPermission() throws Exception { 668 doThrow(new SecurityException()).when(mContext) 669 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 670 eq("WifiService")); 671 try { 672 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false); 673 fail(); 674 } catch (SecurityException e) { } 675 } 676 677 /** 678 * Verify that wifi can be disabled without consent UI popup when permission 679 * review is required but got permission granted. 680 */ 681 @Test 682 public void testSetWifiDisabledSuccessWhenPermissionReviewRequiredAndPermissionGranted() 683 throws Exception { 684 // Set PermissionReviewRequired to true explicitly 685 when(mResources.getBoolean(anyInt())).thenReturn(true); 686 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 687 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 688 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 689 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED); 690 when(mContext.checkCallingPermission( 691 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 692 .thenReturn(PackageManager.PERMISSION_GRANTED); 693 694 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 695 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 696 } 697 698 /** 699 * Verify that wifi is not disabled but got consent UI popup when permission 700 * review is required but do not have permission. 701 */ 702 @Test 703 public void testSetWifiDisabledConsentUiWhenPermissionReviewRequiredAndPermissionDenied() 704 throws Exception { 705 // Set PermissionReviewRequired to true explicitly 706 when(mResources.getBoolean(anyInt())).thenReturn(true); 707 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 708 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 709 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 710 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED); 711 when(mContext.checkCallingPermission( 712 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 713 .thenReturn(PackageManager.PERMISSION_DENIED); 714 when(mPackageManager.getApplicationInfoAsUser( 715 anyString(), anyInt(), anyInt())) 716 .thenReturn(mApplicationInfo); 717 mApplicationInfo.uid = TEST_UID; 718 int uid = Binder.getCallingUid(); 719 BinderUtil.setUid(TEST_UID); 720 721 try { 722 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 723 } finally { 724 BinderUtil.setUid(uid); 725 } 726 verify(mContext).startActivity(any()); 727 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 728 } 729 730 /** 731 * Verify that wifi can be disabled when wifi is on and permission review is 732 * not required. 733 */ 734 @Test 735 public void testSetWifiDisabledSuccessWhenPermissionReviewNotRequired() throws Exception { 736 // Set PermissionReviewRequired to false explicitly 737 when(mResources.getBoolean(anyInt())).thenReturn(false); 738 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 739 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 740 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 741 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED); 742 when(mContext.checkCallingPermission( 743 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 744 .thenReturn(PackageManager.PERMISSION_GRANTED); 745 746 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 747 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 748 } 749 750 /** 751 * Verify a SecurityException is thrown when bringing up Consent UI but caller 752 * uid does not match application uid. 753 * 754 * @throws SecurityException 755 */ 756 @Test 757 public void testSetWifiDisabledThrowsSecurityExceptionForConsentUiIfUidNotMatch() 758 throws Exception { 759 // Set PermissionReviewRequired to true explicitly 760 when(mResources.getBoolean(anyInt())).thenReturn(true); 761 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 762 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 763 when(mSettingsStore.isAirplaneModeOn()).thenReturn(false); 764 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED); 765 when(mContext.checkCallingPermission( 766 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED))) 767 .thenReturn(PackageManager.PERMISSION_DENIED); 768 when(mPackageManager.getApplicationInfoAsUser( 769 anyString(), anyInt(), anyInt())) 770 .thenReturn(mApplicationInfo); 771 mApplicationInfo.uid = TEST_UID; 772 int uid = Binder.getCallingUid(); 773 BinderUtil.setUid(OTHER_TEST_UID); 774 775 try { 776 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false); 777 fail(); 778 } catch (SecurityException e) { 779 780 } finally { 781 // reset Binder uid so we do not mess up other tests 782 BinderUtil.setUid(uid); 783 } 784 } 785 786 /** 787 * Ensure unpermitted callers cannot write the SoftApConfiguration. 788 * 789 * @throws SecurityException 790 */ 791 @Test 792 public void testSetWifiApConfigurationNotSavedWithoutPermission() { 793 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false); 794 WifiConfiguration apConfig = new WifiConfiguration(); 795 try { 796 mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME); 797 fail("Expected SecurityException"); 798 } catch (SecurityException e) { } 799 } 800 801 /** 802 * Ensure softap config is written when the caller has the correct permission. 803 */ 804 @Test 805 public void testSetWifiApConfigurationSuccess() { 806 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 807 WifiConfiguration apConfig = createValidSoftApConfiguration(); 808 809 assertTrue(mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME)); 810 mLooper.dispatchAll(); 811 verifyCheckChangePermission(TEST_PACKAGE_NAME); 812 verify(mWifiApConfigStore).setApConfiguration(eq(apConfig)); 813 } 814 815 /** 816 * Ensure that a null config does not overwrite the saved ap config. 817 */ 818 @Test 819 public void testSetWifiApConfigurationNullConfigNotSaved() { 820 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 821 assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME)); 822 verify(mWifiApConfigStore, never()).setApConfiguration(isNull(WifiConfiguration.class)); 823 } 824 825 /** 826 * Ensure that an invalid config does not overwrite the saved ap config. 827 */ 828 @Test 829 public void testSetWifiApConfigurationWithInvalidConfigNotSaved() { 830 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 831 assertFalse(mWifiServiceImpl.setWifiApConfiguration(new WifiConfiguration(), 832 TEST_PACKAGE_NAME)); 833 verify(mWifiApConfigStore, never()).setApConfiguration(any()); 834 } 835 836 /** 837 * Ensure unpermitted callers are not able to retrieve the softap config. 838 * 839 * @throws SecurityException 840 */ 841 @Test 842 public void testGetWifiApConfigurationNotReturnedWithoutPermission() { 843 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false); 844 try { 845 mWifiServiceImpl.getWifiApConfiguration(); 846 fail("Expected a SecurityException"); 847 } catch (SecurityException e) { 848 } 849 } 850 851 /** 852 * Ensure permitted callers are able to retrieve the softap config. 853 */ 854 @Test 855 public void testGetWifiApConfigurationSuccess() { 856 setupWifiStateMachineHandlerForRunWithScissors(); 857 858 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 859 mWifiServiceImpl.setWifiHandlerLogForTest(mLog); 860 861 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 862 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 863 864 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 865 WifiConfiguration apConfig = new WifiConfiguration(); 866 when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig); 867 assertEquals(apConfig, mWifiServiceImpl.getWifiApConfiguration()); 868 } 869 870 /** 871 * Ensure we return the proper variable for the softap state after getting an AP state change 872 * broadcast. 873 */ 874 @Test 875 public void testGetWifiApEnabled() { 876 // set up WifiServiceImpl with a live thread for testing 877 HandlerThread serviceHandlerThread = createAndStartHandlerThreadForRunWithScissors(); 878 when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(serviceHandlerThread); 879 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 880 mWifiServiceImpl.setWifiHandlerLogForTest(mLog); 881 882 // ap should be disabled when wifi hasn't been started 883 assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState()); 884 885 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 886 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 887 mWifiServiceImpl.checkAndStartWifi(); 888 mLooper.dispatchAll(); 889 890 // ap should be disabled initially 891 assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState()); 892 893 // send an ap state change to verify WifiServiceImpl is updated 894 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 895 (IntentFilter) argThat(new IntentFilterMatcher())); 896 897 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 898 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL, 899 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 900 mLooper.dispatchAll(); 901 902 assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState()); 903 } 904 905 /** 906 * Ensure we do not allow unpermitted callers to get the wifi ap state. 907 */ 908 @Ignore 909 @Test 910 public void testGetWifiApEnabledPermissionDenied() { 911 // we should not be able to get the state 912 doThrow(new SecurityException()).when(mContext) 913 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.ACCESS_WIFI_STATE), 914 eq("WifiService")); 915 916 try { 917 mWifiServiceImpl.getWifiApEnabledState(); 918 fail("expected SecurityException"); 919 } catch (SecurityException expected) { } 920 } 921 922 /** 923 * Make sure we do not start wifi if System services have to be restarted to decrypt the device. 924 */ 925 @Test 926 public void testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot() { 927 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true); 928 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 929 mWifiServiceImpl.checkAndStartWifi(); 930 verify(mWifiController, never()).start(); 931 } 932 933 /** 934 * Make sure we do start WifiController (wifi disabled) if the device is already decrypted. 935 */ 936 @Test 937 public void testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled() { 938 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 939 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 940 mWifiServiceImpl.checkAndStartWifi(); 941 verify(mWifiController).start(); 942 verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED); 943 } 944 945 /** 946 * Make sure we do start WifiController (wifi enabled) if the device is already decrypted. 947 */ 948 @Test 949 public void testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled() { 950 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 951 when(mSettingsStore.handleWifiToggled(true)).thenReturn(true); 952 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 953 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_DISABLED); 954 when(mContext.getPackageName()).thenReturn(ANDROID_SYSTEM_PACKAGE); 955 mWifiServiceImpl.checkAndStartWifi(); 956 verify(mWifiController).start(); 957 verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED); 958 } 959 960 /** 961 * Verify caller with proper permission can call startSoftAp. 962 */ 963 @Test 964 public void testStartSoftApWithPermissionsAndNullConfig() { 965 boolean result = mWifiServiceImpl.startSoftAp(null); 966 assertTrue(result); 967 verify(mWifiController) 968 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 969 assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 970 } 971 972 /** 973 * Verify caller with proper permissions but an invalid config does not start softap. 974 */ 975 @Test 976 public void testStartSoftApWithPermissionsAndInvalidConfig() { 977 boolean result = mWifiServiceImpl.startSoftAp(mApConfig); 978 assertFalse(result); 979 verifyZeroInteractions(mWifiController); 980 } 981 982 /** 983 * Verify caller with proper permission and valid config does start softap. 984 */ 985 @Test 986 public void testStartSoftApWithPermissionsAndValidConfig() { 987 WifiConfiguration config = createValidSoftApConfiguration(); 988 boolean result = mWifiServiceImpl.startSoftAp(config); 989 assertTrue(result); 990 verify(mWifiController) 991 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 992 assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 993 } 994 995 /** 996 * Verify a SecurityException is thrown when a caller without the correct permission attempts to 997 * start softap. 998 */ 999 @Test(expected = SecurityException.class) 1000 public void testStartSoftApWithoutPermissionThrowsException() throws Exception { 1001 doThrow(new SecurityException()).when(mContext) 1002 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK), 1003 eq("WifiService")); 1004 mWifiServiceImpl.startSoftAp(null); 1005 } 1006 1007 /** 1008 * Verify caller with proper permission can call stopSoftAp. 1009 */ 1010 @Test 1011 public void testStopSoftApWithPermissions() { 1012 boolean result = mWifiServiceImpl.stopSoftAp(); 1013 assertTrue(result); 1014 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1015 } 1016 1017 /** 1018 * Verify SecurityException is thrown when a caller without the correct permission attempts to 1019 * stop softap. 1020 */ 1021 @Test(expected = SecurityException.class) 1022 public void testStopSoftApWithoutPermissionThrowsException() throws Exception { 1023 doThrow(new SecurityException()).when(mContext) 1024 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK), 1025 eq("WifiService")); 1026 mWifiServiceImpl.stopSoftAp(); 1027 } 1028 1029 /** 1030 * Ensure that we handle app ops check failure when handling scan request. 1031 */ 1032 @Test 1033 public void testStartScanFailureAppOpsIgnored() { 1034 setupWifiStateMachineHandlerForRunWithScissors(); 1035 doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager) 1036 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME); 1037 assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 1038 verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 1039 } 1040 1041 /** 1042 * Ensure that we handle scan access permission check failure when handling scan request. 1043 */ 1044 @Test 1045 public void testStartScanFailureInCanAccessScanResultsPermission() { 1046 setupWifiStateMachineHandlerForRunWithScissors(); 1047 doThrow(new SecurityException()).when(mWifiPermissionsUtil) 1048 .enforceCanAccessScanResults(SCAN_PACKAGE_NAME, Process.myUid()); 1049 assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 1050 verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 1051 } 1052 1053 /** 1054 * Ensure that we handle scan request failure when posting the runnable to handler fails. 1055 */ 1056 @Ignore 1057 @Test 1058 public void testStartScanFailureInRunWithScissors() { 1059 setupWifiStateMachineHandlerForRunWithScissors(); 1060 doReturn(false).when(mHandlerSpyForWsmRunWithScissors) 1061 .runWithScissors(any(), anyLong()); 1062 assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 1063 verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 1064 } 1065 1066 /** 1067 * Ensure that we handle scan request failure from ScanRequestProxy fails. 1068 */ 1069 @Test 1070 public void testStartScanFailureFromScanRequestProxy() { 1071 setupWifiStateMachineHandlerForRunWithScissors(); 1072 when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false); 1073 assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 1074 verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 1075 } 1076 1077 static final String TEST_SSID = "Sid's Place"; 1078 static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\""; 1079 static final String TEST_BSSID = "01:02:03:04:05:06"; 1080 static final String TEST_PACKAGE = "package"; 1081 1082 private void setupForGetConnectionInfo() { 1083 WifiInfo wifiInfo = new WifiInfo(); 1084 wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); 1085 wifiInfo.setBSSID(TEST_BSSID); 1086 when(mWifiStateMachine.syncRequestConnectionInfo()).thenReturn(wifiInfo); 1087 } 1088 1089 /** 1090 * Test that connected SSID and BSSID are not exposed to an app that does not have the 1091 * appropriate permissions. 1092 */ 1093 @Test 1094 public void testConnectedIdsAreHiddenFromAppWithoutPermission() throws Exception { 1095 setupForGetConnectionInfo(); 1096 1097 doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults( 1098 anyString(), anyInt()); 1099 1100 WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE); 1101 1102 assertEquals(WifiSsid.NONE, connectionInfo.getSSID()); 1103 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID()); 1104 } 1105 1106 /** 1107 * Test that connected SSID and BSSID are not exposed to an app that does not have the 1108 * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException. 1109 */ 1110 @Test 1111 public void testConnectedIdsAreHiddenOnSecurityException() throws Exception { 1112 setupForGetConnectionInfo(); 1113 1114 doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults( 1115 anyString(), anyInt()); 1116 1117 WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE); 1118 1119 assertEquals(WifiSsid.NONE, connectionInfo.getSSID()); 1120 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID()); 1121 } 1122 1123 /** 1124 * Test that connected SSID and BSSID are exposed to an app that does have the 1125 * appropriate permissions. 1126 */ 1127 @Test 1128 public void testConnectedIdsAreVisibleFromPermittedApp() throws Exception { 1129 setupForGetConnectionInfo(); 1130 1131 WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE); 1132 1133 assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID()); 1134 assertEquals(TEST_BSSID, connectionInfo.getBSSID()); 1135 } 1136 1137 /** 1138 * Test fetching of scan results. 1139 */ 1140 @Test 1141 public void testGetScanResults() { 1142 setupWifiStateMachineHandlerForRunWithScissors(); 1143 1144 ScanResult[] scanResults = 1145 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0] 1146 .getResults(); 1147 List<ScanResult> scanResultList = 1148 new ArrayList<>(Arrays.asList(scanResults)); 1149 when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList); 1150 1151 String packageName = "test.com"; 1152 List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName); 1153 verify(mScanRequestProxy).getScanResults(); 1154 1155 ScanTestUtil.assertScanResultsEquals(scanResults, 1156 retrievedScanResultList.toArray(new ScanResult[retrievedScanResultList.size()])); 1157 } 1158 1159 /** 1160 * Ensure that we handle scan results failure when posting the runnable to handler fails. 1161 */ 1162 @Ignore 1163 @Test 1164 public void testGetScanResultsFailureInRunWithScissors() { 1165 setupWifiStateMachineHandlerForRunWithScissors(); 1166 doReturn(false).when(mHandlerSpyForWsmRunWithScissors) 1167 .runWithScissors(any(), anyLong()); 1168 1169 ScanResult[] scanResults = 1170 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0] 1171 .getResults(); 1172 List<ScanResult> scanResultList = 1173 new ArrayList<>(Arrays.asList(scanResults)); 1174 when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList); 1175 1176 String packageName = "test.com"; 1177 List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName); 1178 verify(mScanRequestProxy, never()).getScanResults(); 1179 1180 assertTrue(retrievedScanResultList.isEmpty()); 1181 } 1182 1183 private void registerLOHSRequestFull() { 1184 // allow test to proceed without a permission check failure 1185 when(mSettingsStore.getLocationModeSetting(mContext)) 1186 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 1187 try { 1188 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 1189 } catch (RemoteException e) { } 1190 when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) 1191 .thenReturn(false); 1192 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 1193 TEST_PACKAGE_NAME); 1194 assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result); 1195 verifyCheckChangePermission(TEST_PACKAGE_NAME); 1196 } 1197 1198 /** 1199 * Verify that the call to startLocalOnlyHotspot returns REQUEST_REGISTERED when successfully 1200 * called. 1201 */ 1202 @Test 1203 public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() { 1204 registerLOHSRequestFull(); 1205 } 1206 1207 /** 1208 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not 1209 * have the CHANGE_WIFI_STATE permission. 1210 */ 1211 @Test(expected = SecurityException.class) 1212 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() { 1213 doThrow(new SecurityException()).when(mContext) 1214 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 1215 eq("WifiService")); 1216 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1217 } 1218 1219 /** 1220 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not 1221 * have Location permission. 1222 */ 1223 @Test(expected = SecurityException.class) 1224 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission() { 1225 doThrow(new SecurityException()) 1226 .when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME), 1227 anyInt()); 1228 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1229 } 1230 1231 /** 1232 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if Location mode is 1233 * disabled. 1234 */ 1235 @Test(expected = SecurityException.class) 1236 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() { 1237 when(mSettingsStore.getLocationModeSetting(mContext)).thenReturn(LOCATION_MODE_OFF); 1238 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1239 } 1240 1241 /** 1242 * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request. 1243 */ 1244 @Test 1245 public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception { 1246 when(mSettingsStore.getLocationModeSetting(mContext)) 1247 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 1248 1249 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false); 1250 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 1251 TEST_PACKAGE_NAME); 1252 assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result); 1253 } 1254 1255 /** 1256 * Do not register the LocalOnlyHotspot request if the caller app cannot be verified as the 1257 * foreground app at the time of the request (ie, throws an exception in the check). 1258 */ 1259 @Test 1260 public void testStartLocalOnlyHotspotFailsIfForegroundAppCheckThrowsRemoteException() 1261 throws Exception { 1262 when(mSettingsStore.getLocationModeSetting(mContext)) 1263 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 1264 1265 when(mFrameworkFacade.isAppForeground(anyInt())).thenThrow(new RemoteException()); 1266 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 1267 TEST_PACKAGE_NAME); 1268 assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result); 1269 } 1270 1271 /** 1272 * Only start LocalOnlyHotspot if we are not tethering. 1273 */ 1274 @Test 1275 public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception { 1276 when(mSettingsStore.getLocationModeSetting(mContext)) 1277 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 1278 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 1279 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 1280 mLooper.dispatchAll(); 1281 int returnCode = mWifiServiceImpl.startLocalOnlyHotspot( 1282 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1283 assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode); 1284 } 1285 1286 /** 1287 * Only start LocalOnlyHotspot if admin setting does not disallow tethering. 1288 */ 1289 @Test 1290 public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception { 1291 when(mSettingsStore.getLocationModeSetting(mContext)) 1292 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 1293 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 1294 when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) 1295 .thenReturn(true); 1296 int returnCode = mWifiServiceImpl.startLocalOnlyHotspot( 1297 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1298 assertEquals(ERROR_TETHERING_DISALLOWED, returnCode); 1299 } 1300 1301 /** 1302 * Verify that callers can only have one registered LOHS request. 1303 */ 1304 @Test(expected = IllegalStateException.class) 1305 public void testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered() { 1306 registerLOHSRequestFull(); 1307 1308 // now do the second request that will fail 1309 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 1310 } 1311 1312 /** 1313 * Verify that the call to stopLocalOnlyHotspot does not do anything when there aren't any 1314 * registered callers. 1315 */ 1316 @Test 1317 public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() { 1318 // allow test to proceed without a permission check failure 1319 mWifiServiceImpl.stopLocalOnlyHotspot(); 1320 // there is nothing registered, so this shouldn't do anything 1321 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 1322 } 1323 1324 /** 1325 * Verify that the call to stopLocalOnlyHotspot does not do anything when one caller unregisters 1326 * but there is still an active request 1327 */ 1328 @Test 1329 public void testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest() { 1330 // register a request that will remain after the stopLOHS call 1331 mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo); 1332 1333 registerLOHSRequestFull(); 1334 1335 // Since we are calling with the same pid, the second register call will be removed 1336 mWifiServiceImpl.stopLocalOnlyHotspot(); 1337 // there is still a valid registered request - do not tear down LOHS 1338 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 1339 } 1340 1341 /** 1342 * Verify that the call to stopLocalOnlyHotspot sends a message to WifiController to stop 1343 * the softAp when there is one registered caller when that caller is removed. 1344 */ 1345 @Test 1346 public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() { 1347 registerLOHSRequestFull(); 1348 verify(mWifiController) 1349 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class)); 1350 1351 // No permission check required for change_wifi_state. 1352 verify(mContext, never()).enforceCallingOrSelfPermission( 1353 eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString()); 1354 1355 mWifiServiceImpl.stopLocalOnlyHotspot(); 1356 // there is was only one request registered, we should tear down softap 1357 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1358 } 1359 1360 /** 1361 * Verify that WifiServiceImpl does not send the stop ap message if there were no 1362 * pending LOHS requests upon a binder death callback. 1363 */ 1364 @Test 1365 public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() { 1366 LocalOnlyRequestorCallback binderDeathCallback = 1367 mWifiServiceImpl.new LocalOnlyRequestorCallback(); 1368 1369 binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); 1370 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1371 } 1372 1373 /** 1374 * Verify that WifiServiceImpl does not send the stop ap message if there are remaining 1375 * registered LOHS requests upon a binder death callback. Additionally verify that softap mode 1376 * will be stopped if that remaining request is removed (to verify the binder death properly 1377 * cleared the requestor that died). 1378 */ 1379 @Test 1380 public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests() { 1381 LocalOnlyRequestorCallback binderDeathCallback = 1382 mWifiServiceImpl.new LocalOnlyRequestorCallback(); 1383 1384 // registering a request directly from the test will not trigger a message to start 1385 // softap mode 1386 mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo); 1387 1388 registerLOHSRequestFull(); 1389 1390 binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); 1391 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 1392 1393 reset(mWifiController); 1394 1395 // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder 1396 // death requestor was removed 1397 mWifiServiceImpl.stopLocalOnlyHotspot(); 1398 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1399 } 1400 1401 /** 1402 * Verify that a call to registerSoftApCallback throws a SecurityException if the caller does 1403 * not have NETWORK_SETTINGS permission. 1404 */ 1405 @Test 1406 public void registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() { 1407 doThrow(new SecurityException()).when(mContext) 1408 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 1409 eq("WifiService")); 1410 try { 1411 final int callbackIdentifier = 1; 1412 mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1413 callbackIdentifier); 1414 fail("expected SecurityException"); 1415 } catch (SecurityException expected) { 1416 } 1417 } 1418 1419 /** 1420 * Verify that a call to registerSoftApCallback throws an IllegalArgumentException if the 1421 * parameters are not provided. 1422 */ 1423 @Test 1424 public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() { 1425 try { 1426 final int callbackIdentifier = 1; 1427 mWifiServiceImpl.registerSoftApCallback(mAppBinder, null, callbackIdentifier); 1428 fail("expected IllegalArgumentException"); 1429 } catch (IllegalArgumentException expected) { 1430 } 1431 } 1432 1433 /** 1434 * Verify that a call to unregisterSoftApCallback throws a SecurityException if the caller does 1435 * not have NETWORK_SETTINGS permission. 1436 */ 1437 @Test 1438 public void unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() { 1439 doThrow(new SecurityException()).when(mContext) 1440 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 1441 eq("WifiService")); 1442 try { 1443 final int callbackIdentifier = 1; 1444 mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier); 1445 fail("expected SecurityException"); 1446 } catch (SecurityException expected) { 1447 } 1448 } 1449 1450 /** 1451 * Registers a soft AP callback, then verifies that the current soft AP state and num clients 1452 * are sent to caller immediately after callback is registered. 1453 */ 1454 private void registerSoftApCallbackAndVerify(ISoftApCallback callback, int callbackIdentifier) 1455 throws Exception { 1456 mWifiServiceImpl.registerSoftApCallback(mAppBinder, callback, callbackIdentifier); 1457 mLooper.dispatchAll(); 1458 verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0); 1459 verify(callback).onNumClientsChanged(0); 1460 } 1461 1462 /** 1463 * Verify that registering twice with same callbackIdentifier will replace the first callback. 1464 */ 1465 @Test 1466 public void replacesOldCallbackWithNewCallbackWhenRegisteringTwice() throws Exception { 1467 final int callbackIdentifier = 1; 1468 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1469 registerSoftApCallbackAndVerify(mAnotherSoftApCallback, callbackIdentifier); 1470 1471 final int testNumClients = 4; 1472 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1473 mLooper.dispatchAll(); 1474 // Verify only the second callback is being called 1475 verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); 1476 verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients); 1477 } 1478 1479 /** 1480 * Verify that unregisterSoftApCallback removes callback from registered callbacks list 1481 */ 1482 @Test 1483 public void unregisterSoftApCallbackRemovesCallback() throws Exception { 1484 final int callbackIdentifier = 1; 1485 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1486 1487 mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier); 1488 mLooper.dispatchAll(); 1489 1490 final int testNumClients = 4; 1491 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1492 mLooper.dispatchAll(); 1493 verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); 1494 } 1495 1496 /** 1497 * Verify that unregisterSoftApCallback is no-op if callbackIdentifier not registered. 1498 */ 1499 @Test 1500 public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching() 1501 throws Exception { 1502 final int callbackIdentifier = 1; 1503 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1504 1505 final int differentCallbackIdentifier = 2; 1506 mWifiServiceImpl.unregisterSoftApCallback(differentCallbackIdentifier); 1507 mLooper.dispatchAll(); 1508 1509 final int testNumClients = 4; 1510 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1511 mLooper.dispatchAll(); 1512 verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); 1513 } 1514 1515 /** 1516 * Registers two callbacks, remove one then verify the right callback is being called on events. 1517 */ 1518 @Test 1519 public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception { 1520 final int callbackIdentifier = 1; 1521 mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1522 callbackIdentifier); 1523 1524 // Change state from default before registering the second callback 1525 final int testNumClients = 4; 1526 mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1527 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1528 1529 // Register another callback and verify the new state is returned in the immediate callback 1530 final int anotherUid = 2; 1531 mWifiServiceImpl.registerSoftApCallback(mAppBinder, mAnotherSoftApCallback, anotherUid); 1532 mLooper.dispatchAll(); 1533 verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1534 verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients); 1535 1536 // unregister the fisrt callback 1537 mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier); 1538 mLooper.dispatchAll(); 1539 1540 // Update soft AP state and verify the remaining callback receives the event 1541 mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, 1542 SAP_START_FAILURE_NO_CHANNEL); 1543 mLooper.dispatchAll(); 1544 verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED, 1545 SAP_START_FAILURE_NO_CHANNEL); 1546 verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, 1547 SAP_START_FAILURE_NO_CHANNEL); 1548 } 1549 1550 /** 1551 * Verify that wifi service registers for callers BinderDeath event 1552 */ 1553 @Ignore 1554 @Test 1555 public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception { 1556 final int callbackIdentifier = 1; 1557 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1558 verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 1559 } 1560 1561 /** 1562 * Verify that we un-register the soft AP callback on receiving BinderDied event. 1563 */ 1564 @Test 1565 public void unregistersSoftApCallbackOnBinderDied() throws Exception { 1566 ArgumentCaptor<IBinder.DeathRecipient> drCaptor = 1567 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 1568 final int callbackIdentifier = 1; 1569 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1570 verify(mAppBinder).linkToDeath(drCaptor.capture(), anyInt()); 1571 1572 drCaptor.getValue().binderDied(); 1573 mLooper.dispatchAll(); 1574 verify(mAppBinder).unlinkToDeath(drCaptor.getValue(), 0); 1575 1576 // Verify callback is removed from the list as well 1577 final int testNumClients = 4; 1578 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1579 mLooper.dispatchAll(); 1580 verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); 1581 } 1582 1583 /** 1584 * Verify that soft AP callback is called on NumClientsChanged event 1585 */ 1586 @Test 1587 public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception { 1588 final int callbackIdentifier = 1; 1589 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1590 1591 final int testNumClients = 4; 1592 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1593 mLooper.dispatchAll(); 1594 verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); 1595 } 1596 1597 /** 1598 * Verify that soft AP callback is called on SoftApStateChanged event 1599 */ 1600 @Test 1601 public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception { 1602 final int callbackIdentifier = 1; 1603 registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); 1604 1605 mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1606 mLooper.dispatchAll(); 1607 verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1608 } 1609 1610 /** 1611 * Verify that mSoftApState and mSoftApNumClients in WifiServiceImpl are being updated on soft 1612 * Ap events, even when no callbacks are registered. 1613 */ 1614 @Test 1615 public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception { 1616 final int testNumClients = 4; 1617 mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1618 mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); 1619 1620 // Register callback after num clients and soft AP are changed. 1621 final int callbackIdentifier = 1; 1622 mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1623 callbackIdentifier); 1624 mLooper.dispatchAll(); 1625 verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0); 1626 verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); 1627 } 1628 1629 private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> { 1630 @Override 1631 public boolean matches(IntentFilter filter) { 1632 return filter.hasAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 1633 } 1634 } 1635 1636 /** 1637 * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1638 * broadcast is received. 1639 */ 1640 @Test 1641 public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception { 1642 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1643 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1644 mWifiServiceImpl.checkAndStartWifi(); 1645 1646 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1647 (IntentFilter) argThat(new IntentFilterMatcher())); 1648 1649 registerLOHSRequestFull(); 1650 1651 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1652 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL, 1653 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1654 mLooper.dispatchAll(); 1655 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1656 Message message = mMessageCaptor.getValue(); 1657 assertEquals(HOTSPOT_FAILED, message.what); 1658 assertEquals(ERROR_GENERIC, message.arg1); 1659 } 1660 1661 /** 1662 * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1663 * broadcast is received with the SAP_START_FAILURE_NO_CHANNEL error. 1664 */ 1665 @Test 1666 public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception { 1667 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1668 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1669 mWifiServiceImpl.checkAndStartWifi(); 1670 1671 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1672 (IntentFilter) argThat(new IntentFilterMatcher())); 1673 1674 registerLOHSRequestFull(); 1675 1676 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1677 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL, 1678 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1679 1680 mLooper.dispatchAll(); 1681 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1682 Message message = mMessageCaptor.getValue(); 1683 assertEquals(HOTSPOT_FAILED, message.what); 1684 assertEquals(ERROR_NO_CHANNEL, message.arg1); 1685 } 1686 1687 /** 1688 * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1689 * broadcast is received with WIFI_AP_STATE_DISABLING and LOHS was active. 1690 */ 1691 @Test 1692 public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception { 1693 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1694 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1695 mWifiServiceImpl.checkAndStartWifi(); 1696 1697 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1698 (IntentFilter) argThat(new IntentFilterMatcher())); 1699 1700 registerLOHSRequestFull(); 1701 1702 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1703 mLooper.dispatchAll(); 1704 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1705 Message message = mMessageCaptor.getValue(); 1706 assertEquals(HOTSPOT_STARTED, message.what); 1707 reset(mHandler); 1708 1709 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1710 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1711 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1712 1713 mLooper.dispatchAll(); 1714 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1715 message = mMessageCaptor.getValue(); 1716 assertEquals(HOTSPOT_STOPPED, message.what); 1717 } 1718 1719 1720 /** 1721 * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1722 * broadcast is received with WIFI_AP_STATE_DISABLED and LOHS was enabled. 1723 */ 1724 @Test 1725 public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception { 1726 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1727 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1728 mWifiServiceImpl.checkAndStartWifi(); 1729 1730 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1731 (IntentFilter) argThat(new IntentFilterMatcher())); 1732 1733 registerLOHSRequestFull(); 1734 1735 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1736 mLooper.dispatchAll(); 1737 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1738 Message message = mMessageCaptor.getValue(); 1739 assertEquals(HOTSPOT_STARTED, message.what); 1740 reset(mHandler); 1741 1742 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1743 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1744 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1745 1746 mLooper.dispatchAll(); 1747 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1748 message = mMessageCaptor.getValue(); 1749 assertEquals(HOTSPOT_STOPPED, message.what); 1750 } 1751 1752 /** 1753 * Verify that no callbacks are called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1754 * broadcast is received and the softap started. 1755 */ 1756 @Test 1757 public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception { 1758 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1759 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1760 mWifiServiceImpl.checkAndStartWifi(); 1761 1762 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1763 (IntentFilter) argThat(new IntentFilterMatcher())); 1764 1765 registerLOHSRequestFull(); 1766 1767 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1768 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, 1769 IFACE_IP_MODE_LOCAL_ONLY); 1770 1771 mLooper.dispatchAll(); 1772 verify(mHandler, never()).handleMessage(any(Message.class)); 1773 } 1774 1775 /** 1776 * Verify that onStopped is called only once for registered LOHS callers when 1777 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLING and 1778 * WIFI_AP_STATE_DISABLED when LOHS was enabled. 1779 */ 1780 @Test 1781 public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception { 1782 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1783 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1784 mWifiServiceImpl.checkAndStartWifi(); 1785 1786 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1787 (IntentFilter) argThat(new IntentFilterMatcher())); 1788 1789 registerLOHSRequestFull(); 1790 1791 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1792 mLooper.dispatchAll(); 1793 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1794 Message message = mMessageCaptor.getValue(); 1795 assertEquals(HOTSPOT_STARTED, message.what); 1796 reset(mHandler); 1797 1798 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1799 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1800 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1801 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1802 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1803 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1804 1805 mLooper.dispatchAll(); 1806 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1807 message = mMessageCaptor.getValue(); 1808 assertEquals(HOTSPOT_STOPPED, message.what); 1809 } 1810 1811 /** 1812 * Verify that onFailed is called only once for registered LOHS callers when 1813 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED twice. 1814 */ 1815 @Test 1816 public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception { 1817 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1818 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1819 mWifiServiceImpl.checkAndStartWifi(); 1820 1821 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1822 (IntentFilter) argThat(new IntentFilterMatcher())); 1823 1824 registerLOHSRequestFull(); 1825 1826 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1827 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1828 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1829 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1830 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1831 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1832 1833 mLooper.dispatchAll(); 1834 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1835 Message message = mMessageCaptor.getValue(); 1836 assertEquals(HOTSPOT_FAILED, message.what); 1837 assertEquals(ERROR_GENERIC, message.arg1); 1838 } 1839 1840 /** 1841 * Verify that onFailed is called for all registered LOHS callers when 1842 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED. 1843 */ 1844 @Test 1845 public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception { 1846 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1847 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1848 mWifiServiceImpl.checkAndStartWifi(); 1849 1850 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1851 (IntentFilter) argThat(new IntentFilterMatcher())); 1852 1853 // make an additional request for this test 1854 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1855 1856 registerLOHSRequestFull(); 1857 1858 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1859 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1860 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1861 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1862 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1863 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1864 1865 verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC); 1866 mLooper.dispatchAll(); 1867 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1868 Message message = mMessageCaptor.getValue(); 1869 assertEquals(HOTSPOT_FAILED, message.what); 1870 assertEquals(ERROR_GENERIC, message.arg1); 1871 } 1872 1873 /** 1874 * Verify that onStopped is called for all registered LOHS callers when 1875 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was 1876 * active. 1877 */ 1878 @Test 1879 public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception { 1880 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1881 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1882 mWifiServiceImpl.checkAndStartWifi(); 1883 1884 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1885 (IntentFilter) argThat(new IntentFilterMatcher())); 1886 1887 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1888 1889 registerLOHSRequestFull(); 1890 1891 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1892 mLooper.dispatchAll(); 1893 verify(mRequestInfo).sendHotspotStartedMessage(any()); 1894 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1895 Message message = mMessageCaptor.getValue(); 1896 assertEquals(HOTSPOT_STARTED, message.what); 1897 reset(mHandler); 1898 1899 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1900 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1901 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1902 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1903 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1904 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1905 1906 verify(mRequestInfo).sendHotspotStoppedMessage(); 1907 mLooper.dispatchAll(); 1908 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1909 message = mMessageCaptor.getValue(); 1910 assertEquals(HOTSPOT_STOPPED, message.what); 1911 } 1912 1913 /** 1914 * Verify that onFailed is called for all registered LOHS callers when 1915 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was 1916 * not active. 1917 */ 1918 @Test 1919 public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception { 1920 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1921 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1922 mWifiServiceImpl.checkAndStartWifi(); 1923 1924 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1925 (IntentFilter) argThat(new IntentFilterMatcher())); 1926 1927 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1928 mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2); 1929 1930 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1931 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1932 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1933 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1934 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1935 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1936 1937 verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC); 1938 verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC); 1939 } 1940 1941 /** 1942 * Verify that if we do not have registered LOHS requestors and we receive an update that LOHS 1943 * is up and ready for use, we tell WifiController to tear it down. This can happen if softap 1944 * mode fails to come up properly and we get an onFailed message for a tethering call and we 1945 * had registered callers for LOHS. 1946 */ 1947 @Test 1948 public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() { 1949 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1950 mLooper.dispatchAll(); 1951 1952 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1953 } 1954 1955 /** 1956 * Verify that all registered LOHS requestors are notified via a HOTSPOT_STARTED message that 1957 * the hotspot is up and ready to use. 1958 */ 1959 @Test 1960 public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady() 1961 throws Exception { 1962 registerLOHSRequestFull(); 1963 1964 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1965 1966 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1967 mLooper.dispatchAll(); 1968 verify(mRequestInfo).sendHotspotStartedMessage(any(WifiConfiguration.class)); 1969 1970 mLooper.dispatchAll(); 1971 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1972 Message message = mMessageCaptor.getValue(); 1973 assertEquals(HOTSPOT_STARTED, message.what); 1974 assertNotNull((WifiConfiguration) message.obj); 1975 } 1976 1977 /** 1978 * Verify that if a LOHS is already active, a new call to register a request will trigger the 1979 * onStarted callback. 1980 */ 1981 @Test 1982 public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback() 1983 throws Exception { 1984 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1985 1986 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1987 mLooper.dispatchAll(); 1988 1989 registerLOHSRequestFull(); 1990 1991 mLooper.dispatchAll(); 1992 1993 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1994 Message message = mMessageCaptor.getValue(); 1995 assertEquals(HOTSPOT_STARTED, message.what); 1996 // since the first request was registered out of band, the config will be null 1997 assertNull((WifiConfiguration) message.obj); 1998 } 1999 2000 /** 2001 * Verify that if a LOHS request is active and we receive an update with an ip mode 2002 * configuration error, callers are notified via the onFailed callback with the generic 2003 * error and are unregistered. 2004 */ 2005 @Test 2006 public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception { 2007 registerLOHSRequestFull(); 2008 2009 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); 2010 mLooper.dispatchAll(); 2011 2012 verify(mHandler).handleMessage(mMessageCaptor.capture()); 2013 Message message = mMessageCaptor.getValue(); 2014 assertEquals(HOTSPOT_FAILED, message.what); 2015 assertEquals(ERROR_GENERIC, message.arg1); 2016 2017 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 2018 2019 // sendMessage should only happen once since the requestor should be unregistered 2020 reset(mHandler); 2021 2022 // send HOTSPOT_FAILED message should only happen once since the requestor should be 2023 // unregistered 2024 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); 2025 mLooper.dispatchAll(); 2026 verify(mHandler, never()).handleMessage(any(Message.class)); 2027 } 2028 2029 /** 2030 * Verify that softap mode is stopped for tethering if we receive an update with an ip mode 2031 * configuration error. 2032 */ 2033 @Test 2034 public void testStopSoftApWhenIpConfigFails() throws Exception { 2035 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); 2036 mLooper.dispatchAll(); 2037 2038 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 2039 } 2040 2041 /** 2042 * Verify that if a LOHS request is active and tethering starts, callers are notified on the 2043 * incompatible mode and are unregistered. 2044 */ 2045 @Test 2046 public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception { 2047 registerLOHSRequestFull(); 2048 2049 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 2050 mLooper.dispatchAll(); 2051 2052 verify(mHandler).handleMessage(mMessageCaptor.capture()); 2053 Message message = mMessageCaptor.getValue(); 2054 assertEquals(HOTSPOT_FAILED, message.what); 2055 assertEquals(ERROR_INCOMPATIBLE_MODE, message.arg1); 2056 2057 // sendMessage should only happen once since the requestor should be unregistered 2058 reset(mHandler); 2059 2060 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 2061 mLooper.dispatchAll(); 2062 verify(mHandler, never()).handleMessage(any(Message.class)); 2063 } 2064 2065 /** 2066 * Verify that if LOHS is disabled, a new call to register a request will not trigger the 2067 * onStopped callback. 2068 */ 2069 @Test 2070 public void testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback() 2071 throws Exception { 2072 registerLOHSRequestFull(); 2073 mLooper.dispatchAll(); 2074 2075 verify(mHandler, never()).handleMessage(any(Message.class)); 2076 } 2077 2078 /** 2079 * Verify that if a LOHS was active and then stopped, a new call to register a request will 2080 * not trigger the onStarted callback. 2081 */ 2082 @Test 2083 public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback() 2084 throws Exception { 2085 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 2086 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 2087 mWifiServiceImpl.checkAndStartWifi(); 2088 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2089 (IntentFilter) argThat(new IntentFilterMatcher())); 2090 2091 // register a request so we don't drop the LOHS interface ip update 2092 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 2093 2094 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 2095 mLooper.dispatchAll(); 2096 2097 registerLOHSRequestFull(); 2098 mLooper.dispatchAll(); 2099 2100 verify(mHandler).handleMessage(mMessageCaptor.capture()); 2101 assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what); 2102 2103 reset(mHandler); 2104 2105 // now stop the hotspot 2106 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 2107 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 2108 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 2109 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 2110 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 2111 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 2112 mLooper.dispatchAll(); 2113 verify(mHandler).handleMessage(mMessageCaptor.capture()); 2114 assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what); 2115 2116 reset(mHandler); 2117 2118 // now register a new caller - they should not get the onStarted callback 2119 Messenger messenger2 = new Messenger(mHandler); 2120 IBinder binder2 = mock(IBinder.class); 2121 2122 int result = mWifiServiceImpl.startLocalOnlyHotspot(messenger2, binder2, TEST_PACKAGE_NAME); 2123 assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result); 2124 mLooper.dispatchAll(); 2125 2126 verify(mHandler, never()).handleMessage(any(Message.class)); 2127 } 2128 2129 /** 2130 * Verify that a call to startWatchLocalOnlyHotspot is only allowed from callers with the 2131 * signature only NETWORK_SETTINGS permission. 2132 * 2133 * This test is expecting the permission check to enforce the permission and throw a 2134 * SecurityException for callers without the permission. This exception should be bubbled up to 2135 * the caller of startLocalOnlyHotspot. 2136 */ 2137 @Test(expected = SecurityException.class) 2138 public void testStartWatchLocalOnlyHotspotNotApprovedCaller() { 2139 doThrow(new SecurityException()).when(mContext) 2140 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2141 eq("WifiService")); 2142 mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder); 2143 } 2144 2145 /** 2146 * Verify that the call to startWatchLocalOnlyHotspot throws the UnsupportedOperationException 2147 * when called until the implementation is complete. 2148 */ 2149 @Test(expected = UnsupportedOperationException.class) 2150 public void testStartWatchLocalOnlyHotspotNotSupported() { 2151 mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder); 2152 } 2153 2154 /** 2155 * Verify that a call to stopWatchLocalOnlyHotspot is only allowed from callers with the 2156 * signature only NETWORK_SETTINGS permission. 2157 */ 2158 @Test(expected = SecurityException.class) 2159 public void testStopWatchLocalOnlyHotspotNotApprovedCaller() { 2160 doThrow(new SecurityException()).when(mContext) 2161 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2162 eq("WifiService")); 2163 mWifiServiceImpl.stopWatchLocalOnlyHotspot(); 2164 } 2165 2166 /** 2167 * Verify that the call to stopWatchLocalOnlyHotspot throws the UnsupportedOperationException 2168 * until the implementation is complete. 2169 */ 2170 @Test(expected = UnsupportedOperationException.class) 2171 public void testStopWatchLocalOnlyHotspotNotSupported() { 2172 mWifiServiceImpl.stopWatchLocalOnlyHotspot(); 2173 } 2174 2175 /** 2176 * Verify that the call to addOrUpdateNetwork for installing Passpoint profile is redirected 2177 * to the Passpoint specific API addOrUpdatePasspointConfiguration. 2178 */ 2179 @Test 2180 public void testAddPasspointProfileViaAddNetwork() throws Exception { 2181 WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork(); 2182 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 2183 2184 PackageManager pm = mock(PackageManager.class); 2185 when(pm.hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true); 2186 when(mContext.getPackageManager()).thenReturn(pm); 2187 2188 when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(), 2189 any(PasspointConfiguration.class), anyInt())).thenReturn(true); 2190 assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME)); 2191 verifyCheckChangePermission(TEST_PACKAGE_NAME); 2192 verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(), 2193 any(PasspointConfiguration.class), anyInt()); 2194 reset(mWifiStateMachine); 2195 2196 when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(), 2197 any(PasspointConfiguration.class), anyInt())).thenReturn(false); 2198 assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME)); 2199 verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(), 2200 any(PasspointConfiguration.class), anyInt()); 2201 } 2202 2203 /** 2204 * Verify that the call to startSubscriptionProvisioning is redirected to the Passpoint 2205 * specific API startSubscriptionProvisioning when the caller has the right permissions. 2206 */ 2207 @Test 2208 public void testStartSubscriptionProvisioningWithPermission() throws Exception { 2209 mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback); 2210 verify(mWifiStateMachine).syncStartSubscriptionProvisioning(anyInt(), 2211 eq(mOsuProvider), eq(mProvisioningCallback), any()); 2212 } 2213 2214 /** 2215 * Verify that the call to startSubscriptionProvisioning is not directed to the Passpoint 2216 * specific API startSubscriptionProvisioning when the feature is not supported. 2217 */ 2218 @Test(expected = UnsupportedOperationException.class) 2219 public void testStartSubscriptionProvisioniningPasspointUnsupported() throws Exception { 2220 when(mPackageManager.hasSystemFeature( 2221 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false); 2222 mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback); 2223 } 2224 2225 /** 2226 * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint 2227 * specific API startSubscriptionProvisioning when the caller provides invalid arguments 2228 */ 2229 @Test(expected = IllegalArgumentException.class) 2230 public void testStartSubscriptionProvisioningWithInvalidProvider() throws Exception { 2231 mWifiServiceImpl.startSubscriptionProvisioning(null, mProvisioningCallback); 2232 } 2233 2234 2235 /** 2236 * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint 2237 * specific API startSubscriptionProvisioning when the caller provides invalid callback 2238 */ 2239 @Test(expected = IllegalArgumentException.class) 2240 public void testStartSubscriptionProvisioningWithInvalidCallback() throws Exception { 2241 mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, null); 2242 } 2243 2244 /** 2245 * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint 2246 * specific API startSubscriptionProvisioning when the caller doesn't have NETWORK_SETTINGS 2247 * permissions. 2248 */ 2249 @Test(expected = SecurityException.class) 2250 public void testStartSubscriptionProvisioningWithoutPermission() throws Exception { 2251 doThrow(new SecurityException()).when(mContext) 2252 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2253 eq("WifiService")); 2254 mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback); 2255 } 2256 2257 /** 2258 * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from 2259 * callers with the signature only NETWORK_SETTINGS permission. 2260 */ 2261 @Test(expected = SecurityException.class) 2262 public void testRestoreBackupDataNotApprovedCaller() { 2263 doThrow(new SecurityException()).when(mContext) 2264 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2265 eq("WifiService")); 2266 mWifiServiceImpl.restoreBackupData(null); 2267 verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class)); 2268 } 2269 2270 /** 2271 * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is 2272 * only allowed from callers with the signature only NETWORK_SETTINGS permission. 2273 */ 2274 @Ignore 2275 @Test(expected = SecurityException.class) 2276 public void testRestoreSupplicantBackupDataNotApprovedCaller() { 2277 doThrow(new SecurityException()).when(mContext) 2278 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2279 eq("WifiService")); 2280 mWifiServiceImpl.restoreSupplicantBackupData(null, null); 2281 verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData( 2282 any(byte[].class), any(byte[].class)); 2283 } 2284 2285 /** 2286 * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from 2287 * callers with the signature only NETWORK_SETTINGS permission. 2288 */ 2289 @Test(expected = SecurityException.class) 2290 public void testRetrieveBackupDataNotApprovedCaller() { 2291 doThrow(new SecurityException()).when(mContext) 2292 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2293 eq("WifiService")); 2294 mWifiServiceImpl.retrieveBackupData(); 2295 verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class)); 2296 } 2297 2298 /** 2299 * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is allowed from 2300 * callers with the signature only NETWORK_SETTINGS permission. 2301 */ 2302 @Ignore("TODO: Investigate failure") 2303 @Test 2304 public void testEnableVerboseLoggingWithNetworkSettingsPermission() { 2305 doNothing().when(mContext) 2306 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2307 eq("WifiService")); 2308 mWifiServiceImpl.enableVerboseLogging(1); 2309 verify(mWifiStateMachine).enableVerboseLogging(anyInt()); 2310 } 2311 2312 /** 2313 * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is not allowed from 2314 * callers without the signature only NETWORK_SETTINGS permission. 2315 */ 2316 @Test(expected = SecurityException.class) 2317 public void testEnableVerboseLoggingWithNoNetworkSettingsPermission() { 2318 doThrow(new SecurityException()).when(mContext) 2319 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2320 eq("WifiService")); 2321 mWifiServiceImpl.enableVerboseLogging(1); 2322 verify(mWifiStateMachine, never()).enableVerboseLogging(anyInt()); 2323 } 2324 2325 /** 2326 * Helper to test handling of async messages by wifi service when the message comes from an 2327 * app without {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission. 2328 */ 2329 private void verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2330 int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException { 2331 WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected(); 2332 2333 int uidWithoutPermission = 5; 2334 when(mWifiPermissionsUtil.checkChangePermission(eq(uidWithoutPermission))) 2335 .thenReturn(false); 2336 2337 Message request = Message.obtain(); 2338 request.what = requestMsgWhat; 2339 request.sendingUid = uidWithoutPermission; 2340 2341 mLooper.startAutoDispatch(); 2342 Message reply = tester.sendMessageSynchronously(request); 2343 mLooper.stopAutoDispatch(); 2344 2345 verify(mWifiStateMachine, never()).sendMessage(any(Message.class)); 2346 assertEquals(expectedReplyMsgwhat, reply.what); 2347 assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1); 2348 } 2349 2350 /** 2351 * Verify that the CONNECT_NETWORK message received from an app without 2352 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2353 * error code. 2354 */ 2355 @Test 2356 public void testConnectNetworkWithoutChangePermission() throws Exception { 2357 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2358 WifiManager.CONNECT_NETWORK, WifiManager.CONNECT_NETWORK_FAILED); 2359 } 2360 2361 /** 2362 * Verify that the FORGET_NETWORK message received from an app without 2363 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2364 * error code. 2365 */ 2366 @Test 2367 public void testForgetNetworkWithoutChangePermission() throws Exception { 2368 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2369 WifiManager.SAVE_NETWORK, WifiManager.SAVE_NETWORK_FAILED); 2370 } 2371 2372 /** 2373 * Verify that the START_WPS message received from an app without 2374 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2375 * error code. 2376 */ 2377 @Test 2378 public void testStartWpsWithoutChangePermission() throws Exception { 2379 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2380 WifiManager.START_WPS, WifiManager.WPS_FAILED); 2381 } 2382 2383 /** 2384 * Verify that the CANCEL_WPS message received from an app without 2385 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2386 * error code. 2387 */ 2388 @Test 2389 public void testCancelWpsWithoutChangePermission() throws Exception { 2390 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2391 WifiManager.CANCEL_WPS, WifiManager.CANCEL_WPS_FAILED); 2392 } 2393 2394 /** 2395 * Verify that the DISABLE_NETWORK message received from an app without 2396 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2397 * error code. 2398 */ 2399 @Test 2400 public void testDisableNetworkWithoutChangePermission() throws Exception { 2401 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2402 WifiManager.DISABLE_NETWORK, WifiManager.DISABLE_NETWORK_FAILED); 2403 } 2404 2405 /** 2406 * Verify that the RSSI_PKTCNT_FETCH message received from an app without 2407 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct 2408 * error code. 2409 */ 2410 @Test 2411 public void testRssiPktcntFetchWithoutChangePermission() throws Exception { 2412 verifyAsyncChannelMessageHandlingWithoutChangePermisson( 2413 WifiManager.RSSI_PKTCNT_FETCH, WifiManager.RSSI_PKTCNT_FETCH_FAILED); 2414 } 2415 2416 /** 2417 * Helper to test handling of async messages by wifi service when the message comes from an 2418 * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission. 2419 */ 2420 private void verifyAsyncChannelMessageHandlingWithChangePermisson( 2421 int requestMsgWhat, Object requestMsgObj) throws RemoteException { 2422 WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected(); 2423 2424 when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true); 2425 2426 Message request = Message.obtain(); 2427 request.what = requestMsgWhat; 2428 request.obj = requestMsgObj; 2429 2430 tester.sendMessage(request); 2431 mLooper.dispatchAll(); 2432 2433 ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); 2434 verify(mWifiStateMachine).sendMessage(messageArgumentCaptor.capture()); 2435 assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what); 2436 } 2437 2438 /** 2439 * Helper to test handling of async messages by wifi service when the message comes from an 2440 * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission where we 2441 * immediately return an error for deprecated functionality. 2442 */ 2443 private void verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson( 2444 int requestMsgWhat, Object requestMsgObj) throws Exception { 2445 WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected(); 2446 2447 when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true); 2448 2449 Message request = Message.obtain(); 2450 request.what = requestMsgWhat; 2451 request.obj = requestMsgObj; 2452 2453 tester.sendMessage(request); 2454 mLooper.dispatchAll(); 2455 2456 verify(mWifiStateMachine, never()).sendMessage(any()); 2457 } 2458 2459 /** 2460 * Verify that the CONNECT_NETWORK message received from an app with 2461 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2462 * WifiStateMachine. 2463 */ 2464 @Test 2465 public void testConnectNetworkWithChangePermission() throws Exception { 2466 verifyAsyncChannelMessageHandlingWithChangePermisson( 2467 WifiManager.CONNECT_NETWORK, new WifiConfiguration()); 2468 } 2469 2470 /** 2471 * Verify that the SAVE_NETWORK message received from an app with 2472 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2473 * WifiStateMachine. 2474 */ 2475 @Test 2476 public void testSaveNetworkWithChangePermission() throws Exception { 2477 verifyAsyncChannelMessageHandlingWithChangePermisson( 2478 WifiManager.SAVE_NETWORK, new WifiConfiguration()); 2479 } 2480 2481 /** 2482 * Verify that the START_WPS message received from an app with 2483 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2484 * WifiStateMachine. 2485 */ 2486 @Test 2487 public void testStartWpsWithChangePermission() throws Exception { 2488 verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson( 2489 WifiManager.START_WPS, new Object()); 2490 } 2491 2492 /** 2493 * Verify that the CANCEL_WPS message received from an app with 2494 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2495 * WifiStateMachine. 2496 */ 2497 @Test 2498 public void testCancelWpsWithChangePermission() throws Exception { 2499 verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson( 2500 WifiManager.CANCEL_WPS, new Object()); 2501 } 2502 2503 /** 2504 * Verify that the DISABLE_NETWORK message received from an app with 2505 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2506 * WifiStateMachine. 2507 */ 2508 @Test 2509 public void testDisableNetworkWithChangePermission() throws Exception { 2510 verifyAsyncChannelMessageHandlingWithChangePermisson( 2511 WifiManager.DISABLE_NETWORK, new Object()); 2512 } 2513 2514 /** 2515 * Verify that the RSSI_PKTCNT_FETCH message received from an app with 2516 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to 2517 * WifiStateMachine. 2518 */ 2519 @Test 2520 public void testRssiPktcntFetchWithChangePermission() throws Exception { 2521 verifyAsyncChannelMessageHandlingWithChangePermisson( 2522 WifiManager.RSSI_PKTCNT_FETCH, new Object()); 2523 } 2524 2525 /** 2526 * Verify that setCountryCode() calls WifiCountryCode object on succeess. 2527 */ 2528 @Test 2529 public void testSetCountryCode() throws Exception { 2530 mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE); 2531 verify(mWifiCountryCode).setCountryCode(TEST_COUNTRY_CODE); 2532 } 2533 2534 /** 2535 * Verify that setCountryCode() fails and doesn't call WifiCountryCode object 2536 * if the caller doesn't have CONNECTIVITY_INTERNAL permission. 2537 */ 2538 @Test(expected = SecurityException.class) 2539 public void testSetCountryCodeFailsWithoutConnectivityInternalPermission() throws Exception { 2540 doThrow(new SecurityException()).when(mContext) 2541 .enforceCallingOrSelfPermission( 2542 eq(android.Manifest.permission.CONNECTIVITY_INTERNAL), 2543 eq("ConnectivityService")); 2544 mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE); 2545 verify(mWifiCountryCode, never()).setCountryCode(TEST_COUNTRY_CODE); 2546 } 2547 2548 /** 2549 * Set the wifi state machine mock to return a handler created on test thread. 2550 */ 2551 private void setupWifiStateMachineHandlerForRunWithScissors() { 2552 HandlerThread handlerThread = createAndStartHandlerThreadForRunWithScissors(); 2553 mHandlerSpyForWsmRunWithScissors = spy(handlerThread.getThreadHandler()); 2554 when(mWifiInjector.getWifiStateMachineHandler()) 2555 .thenReturn(mHandlerSpyForWsmRunWithScissors); 2556 } 2557 2558 private HandlerThread createAndStartHandlerThreadForRunWithScissors() { 2559 HandlerThread handlerThread = new HandlerThread("ServiceHandlerThreadForTest"); 2560 handlerThread.start(); 2561 return handlerThread; 2562 } 2563 2564 /** 2565 * Tests the scenario when a scan request arrives while the device is idle. In this case 2566 * the scan is done when idle mode ends. 2567 */ 2568 @Test 2569 public void testHandleDelayedScanAfterIdleMode() throws Exception { 2570 setupWifiStateMachineHandlerForRunWithScissors(); 2571 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 2572 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 2573 mWifiServiceImpl.checkAndStartWifi(); 2574 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2575 (IntentFilter) argThat(new IdleModeIntentMatcher())); 2576 2577 // Tell the wifi service that the device became idle. 2578 when(mPowerManager.isDeviceIdleMode()).thenReturn(true); 2579 TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext); 2580 2581 // Send a scan request while the device is idle. 2582 assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 2583 // No scans must be made yet as the device is idle. 2584 verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 2585 2586 // Tell the wifi service that idle mode ended. 2587 when(mPowerManager.isDeviceIdleMode()).thenReturn(false); 2588 TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext); 2589 2590 // Must scan now. 2591 verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME); 2592 // The app ops check is executed with this package's identity (not the identity of the 2593 // original remote caller who requested the scan while idle). 2594 verify(mAppOpsManager).noteOp( 2595 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME); 2596 2597 // Send another scan request. The device is not idle anymore, so it must be executed 2598 // immediately. 2599 assertTrue(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME)); 2600 verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME); 2601 } 2602 2603 /** 2604 * Verify that if the caller has NETWORK_SETTINGS permission, then it doesn't need 2605 * CHANGE_WIFI_STATE permission. 2606 * @throws Exception 2607 */ 2608 @Test 2609 public void testDisconnectWithNetworkSettingsPerm() throws Exception { 2610 when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2611 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); 2612 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission( 2613 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService"); 2614 doThrow(new SecurityException()).when(mAppOpsManager) 2615 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME); 2616 mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME); 2617 verify(mWifiStateMachine).disconnectCommand(); 2618 } 2619 2620 /** 2621 * Verify that if the caller doesn't have NETWORK_SETTINGS permission, it could still 2622 * get access with the CHANGE_WIFI_STATE permission. 2623 * @throws Exception 2624 */ 2625 @Test 2626 public void testDisconnectWithChangeWifiStatePerm() throws Exception { 2627 mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME); 2628 verifyCheckChangePermission(TEST_PACKAGE_NAME); 2629 verify(mWifiStateMachine).disconnectCommand(); 2630 } 2631 2632 /** 2633 * Verify that the operation fails if the caller has neither NETWORK_SETTINGS or 2634 * CHANGE_WIFI_STATE permissions. 2635 * @throws Exception 2636 */ 2637 @Test 2638 public void testDisconnectRejected() throws Exception { 2639 doThrow(new SecurityException()).when(mAppOpsManager) 2640 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME); 2641 try { 2642 mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME); 2643 fail(); 2644 } catch (SecurityException e) { 2645 2646 } 2647 verifyCheckChangePermission(TEST_PACKAGE_NAME); 2648 verify(mWifiStateMachine, never()).disconnectCommand(); 2649 } 2650 2651 @Test 2652 public void testPackageRemovedBroadcastHandling() { 2653 mWifiServiceImpl.checkAndStartWifi(); 2654 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2655 (IntentFilter) argThat((IntentFilter filter) -> 2656 filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED))); 2657 2658 int uid = TEST_UID; 2659 String packageName = TEST_PACKAGE_NAME; 2660 // Send the broadcast 2661 Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED); 2662 intent.putExtra(Intent.EXTRA_UID, uid); 2663 intent.setData(Uri.fromParts("package", packageName, "")); 2664 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2665 2666 verify(mWifiStateMachine).removeAppConfigs(packageName, uid); 2667 2668 mLooper.dispatchAll(); 2669 verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid); 2670 } 2671 2672 @Test 2673 public void testPackageRemovedBroadcastHandlingWithNoUid() { 2674 mWifiServiceImpl.checkAndStartWifi(); 2675 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2676 (IntentFilter) argThat((IntentFilter filter) -> 2677 filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED))); 2678 2679 String packageName = TEST_PACKAGE_NAME; 2680 // Send the broadcast 2681 Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED); 2682 intent.setData(Uri.fromParts("package", packageName, "")); 2683 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2684 2685 verify(mWifiStateMachine, never()).removeAppConfigs(anyString(), anyInt()); 2686 2687 mLooper.dispatchAll(); 2688 verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt()); 2689 } 2690 2691 @Test 2692 public void testPackageRemovedBroadcastHandlingWithNoPackageName() { 2693 mWifiServiceImpl.checkAndStartWifi(); 2694 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2695 (IntentFilter) argThat((IntentFilter filter) -> 2696 filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED))); 2697 2698 int uid = TEST_UID; 2699 // Send the broadcast 2700 Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED); 2701 intent.putExtra(Intent.EXTRA_UID, uid); 2702 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2703 2704 verify(mWifiStateMachine, never()).removeAppConfigs(anyString(), anyInt()); 2705 2706 mLooper.dispatchAll(); 2707 verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt()); 2708 } 2709 2710 @Test 2711 public void testUserRemovedBroadcastHandling() { 2712 mWifiServiceImpl.checkAndStartWifi(); 2713 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2714 (IntentFilter) argThat((IntentFilter filter) -> 2715 filter.hasAction(Intent.ACTION_USER_REMOVED))); 2716 2717 int userHandle = TEST_USER_HANDLE; 2718 // Send the broadcast 2719 Intent intent = new Intent(Intent.ACTION_USER_REMOVED); 2720 intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2721 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2722 2723 verify(mWifiStateMachine).removeUserConfigs(userHandle); 2724 } 2725 2726 @Test 2727 public void testUserRemovedBroadcastHandlingWithWrongIntentAction() { 2728 mWifiServiceImpl.checkAndStartWifi(); 2729 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2730 (IntentFilter) argThat((IntentFilter filter) -> 2731 filter.hasAction(Intent.ACTION_USER_REMOVED))); 2732 2733 int userHandle = TEST_USER_HANDLE; 2734 // Send the broadcast with wrong action 2735 Intent intent = new Intent(Intent.ACTION_USER_FOREGROUND); 2736 intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2737 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2738 2739 verify(mWifiStateMachine, never()).removeUserConfigs(userHandle); 2740 } 2741 2742 /** 2743 * Test for needs5GHzToAnyApBandConversion returns true. Requires the NETWORK_SETTINGS 2744 * permission. 2745 */ 2746 @Test 2747 public void testNeeds5GHzToAnyApBandConversionReturnedTrue() { 2748 when(mResources.getBoolean( 2749 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any))) 2750 .thenReturn(true); 2751 assertTrue(mWifiServiceImpl.needs5GHzToAnyApBandConversion()); 2752 2753 verify(mContext).enforceCallingOrSelfPermission( 2754 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService")); 2755 } 2756 2757 /** 2758 * Test for needs5GHzToAnyApBandConversion returns false. Requires the NETWORK_SETTINGS 2759 * permission. 2760 */ 2761 @Test 2762 public void testNeeds5GHzToAnyApBandConversionReturnedFalse() { 2763 when(mResources.getBoolean( 2764 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any))) 2765 .thenReturn(false); 2766 2767 assertFalse(mWifiServiceImpl.needs5GHzToAnyApBandConversion()); 2768 2769 verify(mContext).enforceCallingOrSelfPermission( 2770 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService")); 2771 } 2772 2773 /** 2774 * The API impl for needs5GHzToAnyApBandConversion requires the NETWORK_SETTINGS permission, 2775 * verify an exception is thrown without holding the permission. 2776 */ 2777 @Test 2778 public void testNeeds5GHzToAnyApBandConversionThrowsWithoutProperPermissions() { 2779 doThrow(new SecurityException()).when(mContext) 2780 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2781 eq("WifiService")); 2782 2783 try { 2784 mWifiServiceImpl.needs5GHzToAnyApBandConversion(); 2785 // should have thrown an exception - fail test 2786 fail(); 2787 } catch (SecurityException e) { 2788 // expected 2789 } 2790 } 2791 2792 2793 private class IdleModeIntentMatcher implements ArgumentMatcher<IntentFilter> { 2794 @Override 2795 public boolean matches(IntentFilter filter) { 2796 return filter.hasAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 2797 } 2798 } 2799 2800 /** 2801 * Verifies that enforceChangePermission(String package) is called and the caller doesn't 2802 * have NETWORK_SETTINGS permission 2803 */ 2804 private void verifyCheckChangePermission(String callingPackageName) { 2805 verify(mContext, atLeastOnce()) 2806 .checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 2807 anyInt(), anyInt()); 2808 verify(mContext, atLeastOnce()).enforceCallingOrSelfPermission( 2809 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService"); 2810 verify(mAppOpsManager, atLeastOnce()).noteOp( 2811 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), callingPackageName); 2812 } 2813 2814 private WifiConfiguration createValidSoftApConfiguration() { 2815 WifiConfiguration apConfig = new WifiConfiguration(); 2816 apConfig.SSID = "TestAp"; 2817 apConfig.preSharedKey = "thisIsABadPassword"; 2818 apConfig.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); 2819 apConfig.apBand = WifiConfiguration.AP_BAND_2GHZ; 2820 2821 return apConfig; 2822 } 2823 2824 /** 2825 * Verifies that sim state change does not set or reset the country code 2826 */ 2827 @Test 2828 public void testSimStateChangeDoesNotResetCountryCode() { 2829 mWifiServiceImpl.checkAndStartWifi(); 2830 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 2831 (IntentFilter) argThat((IntentFilter filter) -> 2832 filter.hasAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED))); 2833 2834 int userHandle = TEST_USER_HANDLE; 2835 // Send the broadcast 2836 Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 2837 intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle); 2838 mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); 2839 verifyNoMoreInteractions(mWifiCountryCode); 2840 } 2841 } 2842