WifiServiceImplTest.java revision a6e534fc17203d535ec786b25aad9ff65afdbbea
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 17package com.android.server.wifi; 18 19import static android.net.wifi.WifiManager.HOTSPOT_FAILED; 20import static android.net.wifi.WifiManager.HOTSPOT_STARTED; 21import static android.net.wifi.WifiManager.HOTSPOT_STOPPED; 22import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR; 23import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 24import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 25import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; 26import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; 27import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; 28import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED; 29import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; 30import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL; 31import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 32import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; 33import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 34import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 35import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; 36import static android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 37import static android.provider.Settings.Secure.LOCATION_MODE_OFF; 38 39import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR; 40import static com.android.server.wifi.WifiController.CMD_SET_AP; 41import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED; 42 43import static org.junit.Assert.assertEquals; 44import static org.junit.Assert.assertFalse; 45import static org.junit.Assert.assertNotNull; 46import static org.junit.Assert.assertNull; 47import static org.junit.Assert.assertTrue; 48import static org.mockito.Matchers.any; 49import static org.mockito.Matchers.anyString; 50import static org.mockito.Matchers.eq; 51import static org.mockito.Mockito.*; 52 53import android.app.ActivityManager; 54import android.app.AppOpsManager; 55import android.content.BroadcastReceiver; 56import android.content.ContentResolver; 57import android.content.Context; 58import android.content.IntentFilter; 59import android.content.pm.PackageManager; 60import android.content.res.Resources; 61import android.net.IpConfiguration; 62import android.net.wifi.ScanSettings; 63import android.net.wifi.WifiConfiguration; 64import android.net.wifi.WifiEnterpriseConfig; 65import android.net.wifi.WifiManager; 66import android.net.wifi.WifiManager.LocalOnlyHotspotCallback; 67import android.net.wifi.hotspot2.PasspointConfiguration; 68import android.os.Handler; 69import android.os.HandlerThread; 70import android.os.IBinder; 71import android.os.IPowerManager; 72import android.os.Looper; 73import android.os.Message; 74import android.os.Messenger; 75import android.os.PowerManager; 76import android.os.Process; 77import android.os.RemoteException; 78import android.os.UserManager; 79import android.os.WorkSource; 80import android.os.test.TestLooper; 81import android.provider.Settings; 82import android.test.suitebuilder.annotation.SmallTest; 83 84import com.android.internal.util.AsyncChannel; 85import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback; 86import com.android.server.wifi.util.WifiAsyncChannel; 87import com.android.server.wifi.util.WifiPermissionsUtil; 88 89 90import org.junit.Before; 91import org.junit.Test; 92import org.mockito.ArgumentCaptor; 93import org.mockito.ArgumentMatcher; 94import org.mockito.Mock; 95import org.mockito.MockitoAnnotations; 96import org.mockito.Spy; 97 98import java.io.FileDescriptor; 99import java.io.PrintWriter; 100import java.io.StringWriter; 101 102/** 103 * Unit tests for {@link WifiServiceImpl}. 104 * 105 * Note: this is intended to build up over time and will not immediately cover the entire file. 106 */ 107@SmallTest 108public class WifiServiceImplTest { 109 110 private static final String TAG = "WifiServiceImplTest"; 111 private static final String SCAN_PACKAGE_NAME = "scanPackage"; 112 private static final String WHITE_LIST_SCAN_PACKAGE_NAME = "whiteListScanPackage"; 113 private static final int DEFAULT_VERBOSE_LOGGING = 0; 114 private static final long WIFI_BACKGROUND_SCAN_INTERVAL = 10000; 115 private static final String ANDROID_SYSTEM_PACKAGE = "android"; 116 private static final String TEST_PACKAGE_NAME = "TestPackage"; 117 private static final String SYSUI_PACKAGE_NAME = "com.android.systemui"; 118 private static final int TEST_PID = 6789; 119 private static final int TEST_PID2 = 9876; 120 private static final String WIFI_IFACE_NAME = "wlan0"; 121 122 private WifiServiceImpl mWifiServiceImpl; 123 private TestLooper mLooper; 124 private PowerManager mPowerManager; 125 private Handler mHandler; 126 private Messenger mAppMessenger; 127 private int mPid; 128 private int mPid2 = Process.myPid(); 129 130 final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = 131 ArgumentCaptor.forClass(BroadcastReceiver.class); 132 final ArgumentCaptor<IntentFilter> mIntentFilterCaptor = 133 ArgumentCaptor.forClass(IntentFilter.class); 134 135 final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class); 136 final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor = 137 ArgumentCaptor.forClass(SoftApModeConfiguration.class); 138 139 @Mock Context mContext; 140 @Mock WifiInjector mWifiInjector; 141 @Mock Clock mClock; 142 @Mock WifiController mWifiController; 143 @Mock WifiTrafficPoller mWifiTrafficPoller; 144 @Mock WifiStateMachine mWifiStateMachine; 145 @Mock HandlerThread mHandlerThread; 146 @Mock AsyncChannel mAsyncChannel; 147 @Mock Resources mResources; 148 @Mock FrameworkFacade mFrameworkFacade; 149 @Mock WifiLockManager mLockManager; 150 @Mock WifiMulticastLockManager mWifiMulticastLockManager; 151 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 152 @Mock WifiBackupRestore mWifiBackupRestore; 153 @Mock WifiMetrics mWifiMetrics; 154 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 155 @Mock WifiSettingsStore mSettingsStore; 156 @Mock ContentResolver mContentResolver; 157 @Mock UserManager mUserManager; 158 @Mock WifiConfiguration mApConfig; 159 @Mock ActivityManager mActivityManager; 160 @Mock AppOpsManager mAppOpsManager; 161 @Mock IBinder mAppBinder; 162 @Mock WifiNotificationController mWifiNotificationController; 163 @Mock LocalOnlyHotspotRequestInfo mRequestInfo; 164 @Mock LocalOnlyHotspotRequestInfo mRequestInfo2; 165 166 @Spy FakeWifiLog mLog; 167 168 private class WifiAsyncChannelTester { 169 private static final String TAG = "WifiAsyncChannelTester"; 170 public static final int CHANNEL_STATE_FAILURE = -1; 171 public static final int CHANNEL_STATE_DISCONNECTED = 0; 172 public static final int CHANNEL_STATE_HALF_CONNECTED = 1; 173 public static final int CHANNEL_STATE_FULLY_CONNECTED = 2; 174 175 private int mState = CHANNEL_STATE_DISCONNECTED; 176 private WifiAsyncChannel mChannel; 177 private WifiLog mAsyncTestLog; 178 179 WifiAsyncChannelTester(WifiInjector wifiInjector) { 180 mAsyncTestLog = wifiInjector.makeLog(TAG); 181 } 182 183 public int getChannelState() { 184 return mState; 185 } 186 187 public void connect(final Looper looper, final Messenger messenger, 188 final Handler incomingMessageHandler) { 189 assertEquals("AsyncChannel must be in disconnected state", 190 CHANNEL_STATE_DISCONNECTED, mState); 191 mChannel = new WifiAsyncChannel(TAG); 192 mChannel.setWifiLog(mLog); 193 Handler handler = new Handler(mLooper.getLooper()) { 194 @Override 195 public void handleMessage(Message msg) { 196 switch (msg.what) { 197 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 198 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 199 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 200 mState = CHANNEL_STATE_HALF_CONNECTED; 201 } else { 202 mState = CHANNEL_STATE_FAILURE; 203 } 204 break; 205 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 206 mState = CHANNEL_STATE_FULLY_CONNECTED; 207 break; 208 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 209 mState = CHANNEL_STATE_DISCONNECTED; 210 break; 211 default: 212 incomingMessageHandler.handleMessage(msg); 213 break; 214 } 215 } 216 }; 217 mChannel.connect(null, handler, messenger); 218 } 219 } 220 221 @Before public void setUp() { 222 MockitoAnnotations.initMocks(this); 223 mLooper = new TestLooper(); 224 mHandler = spy(new Handler(mLooper.getLooper())); 225 mAppMessenger = new Messenger(mHandler); 226 227 when(mRequestInfo.getPid()).thenReturn(mPid); 228 when(mRequestInfo2.getPid()).thenReturn(mPid2); 229 when(mWifiInjector.getUserManager()).thenReturn(mUserManager); 230 when(mWifiInjector.getWifiController()).thenReturn(mWifiController); 231 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 232 when(mWifiInjector.getWifiStateMachine()).thenReturn(mWifiStateMachine); 233 when(mWifiStateMachine.syncInitialize(any())).thenReturn(true); 234 when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread); 235 when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper()); 236 when(mContext.getResources()).thenReturn(mResources); 237 when(mContext.getContentResolver()).thenReturn(mContentResolver); 238 doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(), 239 anyBoolean(), any()); 240 when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager); 241 when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); 242 when(mFrameworkFacade.getLongSetting( 243 eq(mContext), 244 eq(Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS), 245 anyLong())) 246 .thenReturn(WIFI_BACKGROUND_SCAN_INTERVAL); 247 when(mFrameworkFacade.getStringSetting( 248 eq(mContext), 249 eq(Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_PACKAGE_WHITELIST))) 250 .thenReturn(WHITE_LIST_SCAN_PACKAGE_NAME); 251 IPowerManager powerManagerService = mock(IPowerManager.class); 252 mPowerManager = new PowerManager(mContext, powerManagerService, new Handler()); 253 when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE); 254 when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager); 255 WifiAsyncChannel wifiAsyncChannel = new WifiAsyncChannel("WifiServiceImplTest"); 256 wifiAsyncChannel.setWifiLog(mLog); 257 when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(wifiAsyncChannel); 258 when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade); 259 when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager); 260 when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager); 261 when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog); 262 when(mWifiInjector.getWifiBackupRestore()).thenReturn(mWifiBackupRestore); 263 when(mWifiInjector.makeLog(anyString())).thenReturn(mLog); 264 WifiTrafficPoller wifiTrafficPoller = new WifiTrafficPoller(mContext, 265 mLooper.getLooper(), "mockWlan"); 266 when(mWifiInjector.getWifiTrafficPoller()).thenReturn(wifiTrafficPoller); 267 when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil); 268 when(mWifiInjector.getWifiSettingsStore()).thenReturn(mSettingsStore); 269 when(mWifiInjector.getClock()).thenReturn(mClock); 270 when(mWifiInjector.getWifiNotificationController()).thenReturn(mWifiNotificationController); 271 mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel); 272 mWifiServiceImpl.setWifiHandlerLogForTest(mLog); 273 } 274 275 @Test 276 public void testRemoveNetworkUnknown() { 277 assertFalse(mWifiServiceImpl.removeNetwork(-1)); 278 } 279 280 @Test 281 public void testAsyncChannelHalfConnected() { 282 WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector); 283 Handler handler = mock(Handler.class); 284 TestLooper looper = new TestLooper(); 285 channelTester.connect(looper.getLooper(), mWifiServiceImpl.getWifiServiceMessenger(), 286 handler); 287 mLooper.dispatchAll(); 288 assertEquals("AsyncChannel must be half connected", 289 WifiAsyncChannelTester.CHANNEL_STATE_HALF_CONNECTED, 290 channelTester.getChannelState()); 291 } 292 293 /** 294 * Tests the isValid() check for StaticIpConfigurations, ensuring that configurations with null 295 * ipAddress are rejected, and configurations with ipAddresses are valid. 296 */ 297 @Test 298 public void testStaticIpConfigurationValidityCheck() { 299 WifiConfiguration conf = WifiConfigurationTestUtil.createOpenNetwork(); 300 IpConfiguration ipConf = 301 WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy(); 302 conf.setIpConfiguration(ipConf); 303 // Ensure staticIpConfiguration with IP Address is valid 304 assertTrue(mWifiServiceImpl.isValid(conf)); 305 ipConf.staticIpConfiguration.ipAddress = null; 306 // Ensure staticIpConfiguration with null IP Address it is not valid 307 conf.setIpConfiguration(ipConf); 308 assertFalse(mWifiServiceImpl.isValid(conf)); 309 } 310 311 /** 312 * Ensure WifiMetrics.dump() is the only dump called when 'dumpsys wifi WifiMetricsProto' is 313 * called. This is required to support simple metrics collection via dumpsys 314 */ 315 @Test 316 public void testWifiMetricsDump() { 317 mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), 318 new String[]{mWifiMetrics.PROTO_DUMP_ARG}); 319 verify(mWifiMetrics) 320 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class)); 321 verify(mWifiStateMachine, never()) 322 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class)); 323 } 324 325 326 /** 327 * Ensure WifiServiceImpl.dump() doesn't throw an NPE when executed with null args 328 */ 329 @Test 330 public void testDumpNullArgs() { 331 mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); 332 } 333 334 /** 335 * Verify that wifi can be enabled by a caller with WIFI_STATE_CHANGE permission when wifi is 336 * off (no hotspot, no airplane mode). 337 */ 338 @Test 339 public void testSetWifiEnabledSuccess() throws Exception { 340 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 341 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 342 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 343 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 344 } 345 346 /** 347 * Verify that the CMD_TOGGLE_WIFI message won't be sent if wifi is already on. 348 */ 349 @Test 350 public void testSetWifiEnabledNoToggle() throws Exception { 351 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 352 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(false); 353 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 354 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 355 } 356 357 /** 358 * Verify a SecurityException is thrown if a caller does not have the correct permission to 359 * toggle wifi. 360 */ 361 @Test(expected = SecurityException.class) 362 public void testSetWifiEnableWithoutPermission() throws Exception { 363 doThrow(new SecurityException()).when(mContext) 364 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 365 eq("WifiService")); 366 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true); 367 verify(mWifiStateMachine, never()).syncGetWifiApState(); 368 } 369 370 /** 371 * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we 372 * are in softap mode. 373 */ 374 @Test 375 public void testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled() throws Exception { 376 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_ENABLED); 377 when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true); 378 when(mContext.checkCallingOrSelfPermission( 379 eq(android.Manifest.permission.NETWORK_SETTINGS))) 380 .thenReturn(PackageManager.PERMISSION_GRANTED); 381 assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true)); 382 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 383 } 384 385 /** 386 * Verify that a call from an app cannot enable wifi if we are in softap mode. 387 */ 388 @Test 389 public void testSetWifiEnabledFromAppFailsWhenApEnabled() throws Exception { 390 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_ENABLED); 391 when(mContext.checkCallingOrSelfPermission( 392 eq(android.Manifest.permission.NETWORK_SETTINGS))) 393 .thenReturn(PackageManager.PERMISSION_DENIED); 394 assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true)); 395 verify(mSettingsStore, never()).handleWifiToggled(anyBoolean()); 396 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 397 } 398 399 /** 400 * Verify that wifi can be disabled by a caller with WIFI_STATE_CHANGE permission when wifi is 401 * on. 402 */ 403 @Test 404 public void testSetWifiDisabledSuccess() throws Exception { 405 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 406 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true); 407 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 408 verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED)); 409 } 410 411 /** 412 * Verify that CMD_TOGGLE_WIFI message won't be sent if wifi is already off. 413 */ 414 @Test 415 public void testSetWifiDisabledNoToggle() throws Exception { 416 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 417 when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false); 418 assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false)); 419 verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED)); 420 } 421 422 /** 423 * Verify a SecurityException is thrown if a caller does not have the correct permission to 424 * toggle wifi. 425 */ 426 @Test(expected = SecurityException.class) 427 public void testSetWifiDisabledWithoutPermission() throws Exception { 428 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 429 doThrow(new SecurityException()).when(mContext) 430 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 431 eq("WifiService")); 432 mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false); 433 } 434 435 /** 436 * Ensure unpermitted callers cannot write the SoftApConfiguration. 437 * 438 * @throws SecurityException 439 */ 440 @Test(expected = SecurityException.class) 441 public void testSetWifiApConfigurationNotSavedWithoutPermission() { 442 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false); 443 WifiConfiguration apConfig = new WifiConfiguration(); 444 mWifiServiceImpl.setWifiApConfiguration(apConfig); 445 verify(mWifiStateMachine, never()).setWifiApConfiguration(eq(apConfig)); 446 } 447 448 /** 449 * Ensure softap config is written when the caller has the correct permission. 450 */ 451 @Test 452 public void testSetWifiApConfigurationSuccess() { 453 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 454 WifiConfiguration apConfig = new WifiConfiguration(); 455 mWifiServiceImpl.setWifiApConfiguration(apConfig); 456 verify(mWifiStateMachine).setWifiApConfiguration(eq(apConfig)); 457 } 458 459 /** 460 * Ensure that a null config does not overwrite the saved ap config. 461 */ 462 @Test 463 public void testSetWifiApConfigurationNullConfigNotSaved() { 464 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 465 mWifiServiceImpl.setWifiApConfiguration(null); 466 verify(mWifiStateMachine, never()).setWifiApConfiguration(isNull(WifiConfiguration.class)); 467 } 468 469 /** 470 * Ensure unpermitted callers are not able to retrieve the softap config. 471 * 472 * @throws SecurityException 473 */ 474 @Test(expected = SecurityException.class) 475 public void testGetWifiApConfigurationNotReturnedWithoutPermission() { 476 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false); 477 mWifiServiceImpl.getWifiApConfiguration(); 478 verify(mWifiStateMachine, never()).syncGetWifiApConfiguration(); 479 } 480 481 /** 482 * Ensure permitted callers are able to retrieve the softap config. 483 */ 484 @Test 485 public void testGetWifiApConfigurationSuccess() { 486 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 487 WifiConfiguration apConfig = new WifiConfiguration(); 488 when(mWifiStateMachine.syncGetWifiApConfiguration()).thenReturn(apConfig); 489 assertEquals(apConfig, mWifiServiceImpl.getWifiApConfiguration()); 490 } 491 492 /** 493 * Make sure we do not start wifi if System services have to be restarted to decrypt the device. 494 */ 495 @Test 496 public void testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot() { 497 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true); 498 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 499 mWifiServiceImpl.checkAndStartWifi(); 500 verify(mWifiController, never()).start(); 501 } 502 503 /** 504 * Make sure we do start WifiController (wifi disabled) if the device is already decrypted. 505 */ 506 @Test 507 public void testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled() { 508 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 509 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 510 mWifiServiceImpl.checkAndStartWifi(); 511 verify(mWifiController).start(); 512 verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED); 513 } 514 515 /** 516 * Make sure we do start WifiController (wifi enabled) if the device is already decrypted. 517 */ 518 @Test 519 public void testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled() { 520 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 521 when(mSettingsStore.handleWifiToggled(true)).thenReturn(true); 522 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true); 523 when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_DISABLED); 524 when(mWifiStateMachine.syncGetWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); 525 when(mContext.getPackageName()).thenReturn(ANDROID_SYSTEM_PACKAGE); 526 mWifiServiceImpl.checkAndStartWifi(); 527 verify(mWifiController).start(); 528 verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED); 529 } 530 531 /** 532 * Verify setWifiApEnabled works with the correct permissions and a null config. 533 */ 534 @Test 535 public void testSetWifiApEnabledWithProperPermissionsWithNullConfig() { 536 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 537 when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING))) 538 .thenReturn(false); 539 mWifiServiceImpl.setWifiApEnabled(null, true); 540 verify(mWifiController) 541 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 542 assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 543 } 544 545 /** 546 * Verify setWifiApEnabled works with correct permissions and a valid config. 547 * 548 * TODO: should really validate that ap configs have a set of basic config settings b/37280779 549 */ 550 @Test 551 public void testSetWifiApEnabledWithProperPermissionsWithValidConfig() { 552 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 553 when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING))) 554 .thenReturn(false); 555 WifiConfiguration apConfig = new WifiConfiguration(); 556 mWifiServiceImpl.setWifiApEnabled(apConfig, true); 557 verify(mWifiController).sendMessage( 558 eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 559 assertEquals(apConfig, mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 560 } 561 562 /** 563 * Verify setWifiApEnabled when disabling softap with correct permissions sends the correct 564 * message to WifiController. 565 */ 566 @Test 567 public void testSetWifiApEnabledFalseWithProperPermissionsWithNullConfig() { 568 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 569 when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING))) 570 .thenReturn(false); 571 mWifiServiceImpl.setWifiApEnabled(null, false); 572 verify(mWifiController) 573 .sendMessage(eq(CMD_SET_AP), eq(0), eq(0), mSoftApModeConfigCaptor.capture()); 574 assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 575 } 576 577 /** 578 * setWifiApEnabled should fail if the provided config is not valid. 579 */ 580 @Test 581 public void testSetWifiApEnabledWithProperPermissionInvalidConfigFails() { 582 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 583 when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING))) 584 .thenReturn(false); 585 // mApConfig is a mock and the values are not set - triggering the invalid config. Testing 586 // will be improved when we actually do test softap configs in b/37280779 587 mWifiServiceImpl.setWifiApEnabled(mApConfig, true); 588 verify(mWifiController, never()) 589 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class)); 590 } 591 592 /** 593 * setWifiApEnabled should throw a security exception when the caller does not have the correct 594 * permissions. 595 */ 596 @Test(expected = SecurityException.class) 597 public void testSetWifiApEnabledThrowsSecurityExceptionWithoutConfigOverridePermission() 598 throws Exception { 599 doThrow(new SecurityException()).when(mContext) 600 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 601 eq("WifiService")); 602 mWifiServiceImpl.setWifiApEnabled(null, true); 603 } 604 605 /** 606 * setWifiApEnabled should throw a SecurityException when disallow tethering is set for the 607 * user. 608 */ 609 @Test(expected = SecurityException.class) 610 public void testSetWifiApEnabledThrowsSecurityExceptionWithDisallowTethering() 611 throws Exception { 612 when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true); 613 when(mUserManager.hasUserRestriction(eq(UserManager.DISALLOW_CONFIG_TETHERING))) 614 .thenReturn(true); 615 mWifiServiceImpl.setWifiApEnabled(null, true); 616 617 } 618 619 /** 620 * Verify caller with proper permission can call startSoftAp. 621 */ 622 @Test 623 public void testStartSoftApWithPermissionsAndNullConfig() { 624 boolean result = mWifiServiceImpl.startSoftAp(null); 625 assertTrue(result); 626 verify(mWifiController) 627 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 628 assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 629 } 630 631 /** 632 * Verify caller with proper permissions but an invalid config does not start softap. 633 */ 634 @Test 635 public void testStartSoftApWithPermissionsAndInvalidConfig() { 636 boolean result = mWifiServiceImpl.startSoftAp(mApConfig); 637 assertFalse(result); 638 verifyZeroInteractions(mWifiController); 639 } 640 641 /** 642 * Verify caller with proper permission and valid config does start softap. 643 */ 644 @Test 645 public void testStartSoftApWithPermissionsAndValidConfig() { 646 WifiConfiguration config = new WifiConfiguration(); 647 boolean result = mWifiServiceImpl.startSoftAp(config); 648 assertTrue(result); 649 verify(mWifiController) 650 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); 651 assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration()); 652 } 653 654 /** 655 * Verify a SecurityException is thrown when a caller without the correct permission attempts to 656 * start softap. 657 */ 658 @Test(expected = SecurityException.class) 659 public void testStartSoftApWithoutPermissionThrowsException() throws Exception { 660 doThrow(new SecurityException()).when(mContext) 661 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK), 662 eq("WifiService")); 663 mWifiServiceImpl.startSoftAp(null); 664 } 665 666 /** 667 * Verify caller with proper permission can call stopSoftAp. 668 */ 669 @Test 670 public void testStopSoftApWithPermissions() { 671 boolean result = mWifiServiceImpl.stopSoftAp(); 672 assertTrue(result); 673 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 674 } 675 676 /** 677 * Verify SecurityException is thrown when a caller without the correct permission attempts to 678 * stop softap. 679 */ 680 @Test(expected = SecurityException.class) 681 public void testStopSoftApWithoutPermissionThrowsException() throws Exception { 682 doThrow(new SecurityException()).when(mContext) 683 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK), 684 eq("WifiService")); 685 mWifiServiceImpl.stopSoftAp(); 686 } 687 688 /** 689 * Ensure foreground apps can always do wifi scans. 690 */ 691 @Test 692 public void testWifiScanStartedForeground() { 693 when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( 694 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); 695 mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); 696 verify(mWifiStateMachine).startScan( 697 anyInt(), anyInt(), (ScanSettings) eq(null), any(WorkSource.class)); 698 } 699 700 /** 701 * Ensure background apps get throttled when the previous scan is too close. 702 */ 703 @Test 704 public void testWifiScanBackgroundThrottled() { 705 when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( 706 ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); 707 long startMs = 1000; 708 when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); 709 mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); 710 verify(mWifiStateMachine).startScan( 711 anyInt(), anyInt(), (ScanSettings) eq(null), any(WorkSource.class)); 712 713 when(mClock.getElapsedSinceBootMillis()).thenReturn( 714 startMs + WIFI_BACKGROUND_SCAN_INTERVAL - 1000); 715 mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); 716 verify(mWifiStateMachine, times(1)).startScan( 717 anyInt(), anyInt(), (ScanSettings) eq(null), any(WorkSource.class)); 718 } 719 720 /** 721 * Ensure background apps can do wifi scan when the throttle interval reached. 722 */ 723 @Test 724 public void testWifiScanBackgroundNotThrottled() { 725 when(mActivityManager.getPackageImportance(SCAN_PACKAGE_NAME)).thenReturn( 726 ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); 727 long startMs = 1000; 728 when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); 729 mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); 730 verify(mWifiStateMachine).startScan( 731 anyInt(), eq(0), (ScanSettings) eq(null), any(WorkSource.class)); 732 733 when(mClock.getElapsedSinceBootMillis()).thenReturn( 734 startMs + WIFI_BACKGROUND_SCAN_INTERVAL + 1000); 735 mWifiServiceImpl.startScan(null, null, SCAN_PACKAGE_NAME); 736 verify(mWifiStateMachine).startScan( 737 anyInt(), eq(1), (ScanSettings) eq(null), any(WorkSource.class)); 738 } 739 740 /** 741 * Ensure background apps can do wifi scan when the throttle interval reached. 742 */ 743 @Test 744 public void testWifiScanBackgroundWhiteListed() { 745 when(mActivityManager.getPackageImportance(WHITE_LIST_SCAN_PACKAGE_NAME)).thenReturn( 746 ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); 747 long startMs = 1000; 748 when(mClock.getElapsedSinceBootMillis()).thenReturn(startMs); 749 mWifiServiceImpl.startScan(null, null, WHITE_LIST_SCAN_PACKAGE_NAME); 750 verify(mWifiStateMachine).startScan( 751 anyInt(), anyInt(), (ScanSettings) eq(null), any(WorkSource.class)); 752 753 when(mClock.getElapsedSinceBootMillis()).thenReturn( 754 startMs + WIFI_BACKGROUND_SCAN_INTERVAL - 1000); 755 mWifiServiceImpl.startScan(null, null, WHITE_LIST_SCAN_PACKAGE_NAME); 756 verify(mWifiStateMachine, times(2)).startScan( 757 anyInt(), anyInt(), (ScanSettings) eq(null), any(WorkSource.class)); 758 } 759 760 private void registerLOHSRequestFull() { 761 // allow test to proceed without a permission check failure 762 when(mSettingsStore.getLocationModeSetting(mContext)) 763 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 764 try { 765 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 766 } catch (RemoteException e) { } 767 when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) 768 .thenReturn(false); 769 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 770 TEST_PACKAGE_NAME); 771 assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result); 772 } 773 774 /** 775 * Verify that the call to startLocalOnlyHotspot returns REQUEST_REGISTERED when successfully 776 * called. 777 */ 778 @Test 779 public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() { 780 registerLOHSRequestFull(); 781 } 782 783 /** 784 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not 785 * have the CHANGE_WIFI_STATE permission. 786 */ 787 @Test(expected = SecurityException.class) 788 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() { 789 doThrow(new SecurityException()).when(mContext) 790 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 791 eq("WifiService")); 792 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 793 } 794 795 /** 796 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not 797 * have Location permission. 798 */ 799 @Test(expected = SecurityException.class) 800 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission() { 801 when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); 802 doThrow(new SecurityException()) 803 .when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME), 804 anyInt()); 805 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 806 } 807 808 /** 809 * Verify that a call to startLocalOnlyHotspot throws a SecurityException if Location mode is 810 * disabled. 811 */ 812 @Test(expected = SecurityException.class) 813 public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() { 814 when(mSettingsStore.getLocationModeSetting(mContext)).thenReturn(LOCATION_MODE_OFF); 815 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 816 } 817 818 /** 819 * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request. 820 */ 821 @Test 822 public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception { 823 when(mSettingsStore.getLocationModeSetting(mContext)) 824 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 825 826 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false); 827 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 828 TEST_PACKAGE_NAME); 829 assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result); 830 } 831 832 /** 833 * Do not register the LocalOnlyHotspot request if the caller app cannot be verified as the 834 * foreground app at the time of the request (ie, throws an exception in the check). 835 */ 836 @Test 837 public void testStartLocalOnlyHotspotFailsIfForegroundAppCheckThrowsRemoteException() 838 throws Exception { 839 when(mSettingsStore.getLocationModeSetting(mContext)) 840 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 841 842 when(mFrameworkFacade.isAppForeground(anyInt())).thenThrow(new RemoteException()); 843 int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, 844 TEST_PACKAGE_NAME); 845 assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result); 846 } 847 848 /** 849 * Only start LocalOnlyHotspot if we are not tethering. 850 */ 851 @Test 852 public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception { 853 when(mSettingsStore.getLocationModeSetting(mContext)) 854 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 855 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 856 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 857 mLooper.dispatchAll(); 858 int returnCode = mWifiServiceImpl.startLocalOnlyHotspot( 859 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 860 assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode); 861 } 862 863 /** 864 * Only start LocalOnlyHotspot if admin setting does not disallow tethering. 865 */ 866 @Test 867 public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception { 868 when(mSettingsStore.getLocationModeSetting(mContext)) 869 .thenReturn(LOCATION_MODE_HIGH_ACCURACY); 870 when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true); 871 when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) 872 .thenReturn(true); 873 int returnCode = mWifiServiceImpl.startLocalOnlyHotspot( 874 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 875 assertEquals(ERROR_TETHERING_DISALLOWED, returnCode); 876 } 877 878 /** 879 * Verify that callers can only have one registered LOHS request. 880 */ 881 @Test(expected = IllegalStateException.class) 882 public void testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered() { 883 registerLOHSRequestFull(); 884 885 // now do the second request that will fail 886 mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME); 887 } 888 889 /** 890 * Verify that the call to stopLocalOnlyHotspot does not do anything when there aren't any 891 * registered callers. 892 */ 893 @Test 894 public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() { 895 // allow test to proceed without a permission check failure 896 mWifiServiceImpl.stopLocalOnlyHotspot(); 897 // there is nothing registered, so this shouldn't do anything 898 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 899 } 900 901 /** 902 * Verify that the call to stopLocalOnlyHotspot does not do anything when one caller unregisters 903 * but there is still an active request 904 */ 905 @Test 906 public void testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest() { 907 // register a request that will remain after the stopLOHS call 908 mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo); 909 910 registerLOHSRequestFull(); 911 912 // Since we are calling with the same pid, the second register call will be removed 913 mWifiServiceImpl.stopLocalOnlyHotspot(); 914 // there is still a valid registered request - do not tear down LOHS 915 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 916 } 917 918 /** 919 * Verify that the call to stopLocalOnlyHotspot sends a message to WifiController to stop 920 * the softAp when there is one registered caller when that caller is removed. 921 */ 922 @Test 923 public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() { 924 registerLOHSRequestFull(); 925 verify(mWifiController) 926 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class)); 927 928 mWifiServiceImpl.stopLocalOnlyHotspot(); 929 // there is was only one request registered, we should tear down softap 930 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 931 } 932 933 /** 934 * Verify that a call to stopLocalOnlyHotspot throws a SecurityException if the caller does not 935 * have the CHANGE_WIFI_STATE permission. 936 */ 937 @Test(expected = SecurityException.class) 938 public void testStopLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() { 939 doThrow(new SecurityException()).when(mContext) 940 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE), 941 eq("WifiService")); 942 mWifiServiceImpl.stopLocalOnlyHotspot(); 943 } 944 945 /** 946 * Verify that WifiServiceImpl does not send the stop ap message if there were no 947 * pending LOHS requests upon a binder death callback. 948 */ 949 @Test 950 public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() { 951 LocalOnlyRequestorCallback binderDeathCallback = 952 mWifiServiceImpl.new LocalOnlyRequestorCallback(); 953 954 binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); 955 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 956 } 957 958 /** 959 * Verify that WifiServiceImpl does not send the stop ap message if there are remaining 960 * registered LOHS requests upon a binder death callback. Additionally verify that softap mode 961 * will be stopped if that remaining request is removed (to verify the binder death properly 962 * cleared the requestor that died). 963 */ 964 @Test 965 public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests() { 966 LocalOnlyRequestorCallback binderDeathCallback = 967 mWifiServiceImpl.new LocalOnlyRequestorCallback(); 968 969 // registering a request directly from the test will not trigger a message to start 970 // softap mode 971 mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo); 972 973 registerLOHSRequestFull(); 974 975 binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo); 976 verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt()); 977 978 reset(mWifiController); 979 980 // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder 981 // death requestor was removed 982 mWifiServiceImpl.stopLocalOnlyHotspot(); 983 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 984 } 985 986 private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> { 987 @Override 988 public boolean matches(IntentFilter filter) { 989 return filter.hasAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 990 } 991 } 992 993 /** 994 * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 995 * broadcast is received. 996 */ 997 @Test 998 public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception { 999 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1000 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1001 mWifiServiceImpl.checkAndStartWifi(); 1002 1003 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1004 (IntentFilter) argThat(new IntentFilterMatcher())); 1005 1006 registerLOHSRequestFull(); 1007 1008 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1009 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL, 1010 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1011 mLooper.dispatchAll(); 1012 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1013 Message message = mMessageCaptor.getValue(); 1014 assertEquals(HOTSPOT_FAILED, message.what); 1015 assertEquals(ERROR_GENERIC, message.arg1); 1016 } 1017 1018 /** 1019 * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1020 * broadcast is received with the SAP_START_FAILURE_NO_CHANNEL error. 1021 */ 1022 @Test 1023 public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception { 1024 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1025 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1026 mWifiServiceImpl.checkAndStartWifi(); 1027 1028 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1029 (IntentFilter) argThat(new IntentFilterMatcher())); 1030 1031 registerLOHSRequestFull(); 1032 1033 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1034 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL, 1035 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1036 1037 mLooper.dispatchAll(); 1038 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1039 Message message = mMessageCaptor.getValue(); 1040 assertEquals(HOTSPOT_FAILED, message.what); 1041 assertEquals(ERROR_NO_CHANNEL, message.arg1); 1042 } 1043 1044 /** 1045 * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1046 * broadcast is received with WIFI_AP_STATE_DISABLING and LOHS was active. 1047 */ 1048 @Test 1049 public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception { 1050 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1051 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1052 mWifiServiceImpl.checkAndStartWifi(); 1053 1054 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1055 (IntentFilter) argThat(new IntentFilterMatcher())); 1056 1057 registerLOHSRequestFull(); 1058 1059 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1060 mLooper.dispatchAll(); 1061 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1062 Message message = mMessageCaptor.getValue(); 1063 assertEquals(HOTSPOT_STARTED, message.what); 1064 reset(mHandler); 1065 1066 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1067 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1068 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1069 1070 mLooper.dispatchAll(); 1071 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1072 message = mMessageCaptor.getValue(); 1073 assertEquals(HOTSPOT_STOPPED, message.what); 1074 } 1075 1076 1077 /** 1078 * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1079 * broadcast is received with WIFI_AP_STATE_DISABLED and LOHS was enabled. 1080 */ 1081 @Test 1082 public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception { 1083 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1084 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1085 mWifiServiceImpl.checkAndStartWifi(); 1086 1087 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1088 (IntentFilter) argThat(new IntentFilterMatcher())); 1089 1090 registerLOHSRequestFull(); 1091 1092 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1093 mLooper.dispatchAll(); 1094 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1095 Message message = mMessageCaptor.getValue(); 1096 assertEquals(HOTSPOT_STARTED, message.what); 1097 reset(mHandler); 1098 1099 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1100 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1101 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1102 1103 mLooper.dispatchAll(); 1104 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1105 message = mMessageCaptor.getValue(); 1106 assertEquals(HOTSPOT_STOPPED, message.what); 1107 } 1108 1109 /** 1110 * Verify that no callbacks are called for registered LOHS callers when a WIFI_AP_STATE_CHANGE 1111 * broadcast is received and the softap started. 1112 */ 1113 @Test 1114 public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception { 1115 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1116 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1117 mWifiServiceImpl.checkAndStartWifi(); 1118 1119 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1120 (IntentFilter) argThat(new IntentFilterMatcher())); 1121 1122 registerLOHSRequestFull(); 1123 1124 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1125 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME, 1126 IFACE_IP_MODE_LOCAL_ONLY); 1127 1128 mLooper.dispatchAll(); 1129 verifyNoMoreInteractions(mHandler); 1130 } 1131 1132 /** 1133 * Verify that onStopped is called only once for registered LOHS callers when 1134 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLING and 1135 * WIFI_AP_STATE_DISABLED when LOHS was enabled. 1136 */ 1137 @Test 1138 public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception { 1139 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1140 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1141 mWifiServiceImpl.checkAndStartWifi(); 1142 1143 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1144 (IntentFilter) argThat(new IntentFilterMatcher())); 1145 1146 registerLOHSRequestFull(); 1147 1148 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1149 mLooper.dispatchAll(); 1150 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1151 Message message = mMessageCaptor.getValue(); 1152 assertEquals(HOTSPOT_STARTED, message.what); 1153 reset(mHandler); 1154 1155 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1156 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1157 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1158 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1159 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1160 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1161 1162 mLooper.dispatchAll(); 1163 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1164 message = mMessageCaptor.getValue(); 1165 assertEquals(HOTSPOT_STOPPED, message.what); 1166 } 1167 1168 /** 1169 * Verify that onFailed is called only once for registered LOHS callers when 1170 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED twice. 1171 */ 1172 @Test 1173 public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception { 1174 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1175 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1176 mWifiServiceImpl.checkAndStartWifi(); 1177 1178 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1179 (IntentFilter) argThat(new IntentFilterMatcher())); 1180 1181 registerLOHSRequestFull(); 1182 1183 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1184 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1185 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1186 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1187 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1188 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1189 1190 mLooper.dispatchAll(); 1191 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1192 Message message = mMessageCaptor.getValue(); 1193 assertEquals(HOTSPOT_FAILED, message.what); 1194 assertEquals(ERROR_GENERIC, message.arg1); 1195 } 1196 1197 /** 1198 * Verify that onFailed is called for all registered LOHS callers when 1199 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED. 1200 */ 1201 @Test 1202 public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception { 1203 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1204 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1205 mWifiServiceImpl.checkAndStartWifi(); 1206 1207 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1208 (IntentFilter) argThat(new IntentFilterMatcher())); 1209 1210 // make an additional request for this test 1211 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1212 1213 registerLOHSRequestFull(); 1214 1215 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1216 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1217 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1218 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1219 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC, 1220 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1221 1222 verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC); 1223 mLooper.dispatchAll(); 1224 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1225 Message message = mMessageCaptor.getValue(); 1226 assertEquals(HOTSPOT_FAILED, message.what); 1227 assertEquals(ERROR_GENERIC, message.arg1); 1228 } 1229 1230 /** 1231 * Verify that onStopped is called for all registered LOHS callers when 1232 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was 1233 * active. 1234 */ 1235 @Test 1236 public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception { 1237 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1238 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1239 mWifiServiceImpl.checkAndStartWifi(); 1240 1241 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1242 (IntentFilter) argThat(new IntentFilterMatcher())); 1243 1244 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1245 1246 registerLOHSRequestFull(); 1247 1248 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1249 mLooper.dispatchAll(); 1250 verify(mRequestInfo).sendHotspotStartedMessage(any()); 1251 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1252 Message message = mMessageCaptor.getValue(); 1253 assertEquals(HOTSPOT_STARTED, message.what); 1254 reset(mHandler); 1255 1256 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1257 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1258 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1259 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1260 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1261 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1262 1263 verify(mRequestInfo).sendHotspotStoppedMessage(); 1264 mLooper.dispatchAll(); 1265 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1266 message = mMessageCaptor.getValue(); 1267 assertEquals(HOTSPOT_STOPPED, message.what); 1268 } 1269 1270 /** 1271 * Verify that onFailed is called for all registered LOHS callers when 1272 * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was 1273 * not active. 1274 */ 1275 @Test 1276 public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception { 1277 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1278 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1279 mWifiServiceImpl.checkAndStartWifi(); 1280 1281 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1282 (IntentFilter) argThat(new IntentFilterMatcher())); 1283 1284 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1285 mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2); 1286 1287 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1288 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1289 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1290 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1291 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1292 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1293 1294 verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC); 1295 verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC); 1296 } 1297 1298 /** 1299 * Verify that if we do not have registered LOHS requestors and we receive an update that LOHS 1300 * is up and ready for use, we tell WifiController to tear it down. This can happen if softap 1301 * mode fails to come up properly and we get an onFailed message for a tethering call and we 1302 * had registered callers for LOHS. 1303 */ 1304 @Test 1305 public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() { 1306 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1307 mLooper.dispatchAll(); 1308 1309 verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0)); 1310 } 1311 1312 /** 1313 * Verify that all registered LOHS requestors are notified via a HOTSPOT_STARTED message that 1314 * the hotspot is up and ready to use. 1315 */ 1316 @Test 1317 public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady() 1318 throws Exception { 1319 registerLOHSRequestFull(); 1320 1321 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1322 1323 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1324 mLooper.dispatchAll(); 1325 verify(mRequestInfo).sendHotspotStartedMessage(any(WifiConfiguration.class)); 1326 1327 mLooper.dispatchAll(); 1328 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1329 Message message = mMessageCaptor.getValue(); 1330 assertEquals(HOTSPOT_STARTED, message.what); 1331 assertNotNull((WifiConfiguration) message.obj); 1332 } 1333 1334 /** 1335 * Verify that if a LOHS is already active, a new call to register a request will trigger the 1336 * onStarted callback. 1337 */ 1338 @Test 1339 public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback() 1340 throws Exception { 1341 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1342 1343 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1344 mLooper.dispatchAll(); 1345 1346 registerLOHSRequestFull(); 1347 1348 mLooper.dispatchAll(); 1349 1350 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1351 Message message = mMessageCaptor.getValue(); 1352 assertEquals(HOTSPOT_STARTED, message.what); 1353 // since the first request was registered out of band, the config will be null 1354 assertNull((WifiConfiguration) message.obj); 1355 } 1356 1357 /** 1358 * Verify that if a LOHS request is active and we receive an update with an ip mode 1359 * configuration error, callers are notified via the onFailed callback with the generic 1360 * error and are unregistered. 1361 */ 1362 @Test 1363 public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception { 1364 registerLOHSRequestFull(); 1365 1366 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); 1367 mLooper.dispatchAll(); 1368 1369 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1370 Message message = mMessageCaptor.getValue(); 1371 assertEquals(HOTSPOT_FAILED, message.what); 1372 assertEquals(ERROR_GENERIC, message.arg1); 1373 1374 // sendMessage should only happen once since the requestor should be unregistered 1375 reset(mHandler); 1376 1377 // send HOTSPOT_FAILED message should only happen once since the requestor should be 1378 // unregistered 1379 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR); 1380 mLooper.dispatchAll(); 1381 verify(mHandler, never()).handleMessage(any(Message.class)); 1382 } 1383 1384 /** 1385 * Verify that if a LOHS request is active and tethering starts, callers are notified on the 1386 * incompatible mode and are unregistered. 1387 */ 1388 @Test 1389 public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception { 1390 registerLOHSRequestFull(); 1391 1392 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 1393 mLooper.dispatchAll(); 1394 1395 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1396 Message message = mMessageCaptor.getValue(); 1397 assertEquals(HOTSPOT_FAILED, message.what); 1398 assertEquals(ERROR_INCOMPATIBLE_MODE, message.arg1); 1399 1400 // sendMessage should only happen once since the requestor should be unregistered 1401 reset(mHandler); 1402 1403 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED); 1404 mLooper.dispatchAll(); 1405 verify(mHandler, never()).handleMessage(any(Message.class)); 1406 } 1407 1408 /** 1409 * Verify that if LOHS is disabled, a new call to register a request will not trigger the 1410 * onStopped callback. 1411 */ 1412 @Test 1413 public void testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback() 1414 throws Exception { 1415 registerLOHSRequestFull(); 1416 mLooper.dispatchAll(); 1417 1418 verify(mHandler, never()).handleMessage(any(Message.class)); 1419 } 1420 1421 /** 1422 * Verify that if a LOHS was active and then stopped, a new call to register a request will 1423 * not trigger the onStarted callback. 1424 */ 1425 @Test 1426 public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback() 1427 throws Exception { 1428 when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false); 1429 when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false); 1430 mWifiServiceImpl.checkAndStartWifi(); 1431 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 1432 (IntentFilter) argThat(new IntentFilterMatcher())); 1433 1434 // register a request so we don't drop the LOHS interface ip update 1435 mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo); 1436 1437 mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1438 mLooper.dispatchAll(); 1439 1440 registerLOHSRequestFull(); 1441 mLooper.dispatchAll(); 1442 1443 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1444 assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what); 1445 1446 reset(mHandler); 1447 1448 // now stop the hotspot 1449 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1450 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, 1451 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1452 TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext, 1453 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, 1454 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY); 1455 mLooper.dispatchAll(); 1456 verify(mHandler).handleMessage(mMessageCaptor.capture()); 1457 assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what); 1458 1459 reset(mHandler); 1460 1461 // now register a new caller - they should not get the onStarted callback 1462 Messenger messenger2 = new Messenger(mHandler); 1463 IBinder binder2 = mock(IBinder.class); 1464 1465 int result = mWifiServiceImpl.startLocalOnlyHotspot(messenger2, binder2, TEST_PACKAGE_NAME); 1466 assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result); 1467 mLooper.dispatchAll(); 1468 1469 verify(mHandler, never()).handleMessage(any(Message.class)); 1470 } 1471 1472 /** 1473 * Verify that a call to startWatchLocalOnlyHotspot is only allowed from callers with the 1474 * signature only NETWORK_SETTINGS permission. 1475 * 1476 * This test is expecting the permission check to enforce the permission and throw a 1477 * SecurityException for callers without the permission. This exception should be bubbled up to 1478 * the caller of startLocalOnlyHotspot. 1479 */ 1480 @Test(expected = SecurityException.class) 1481 public void testStartWatchLocalOnlyHotspotNotApprovedCaller() { 1482 doThrow(new SecurityException()).when(mContext) 1483 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 1484 eq("WifiService")); 1485 mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder); 1486 } 1487 1488 /** 1489 * Verify that the call to startWatchLocalOnlyHotspot throws the UnsupportedOperationException 1490 * when called until the implementation is complete. 1491 */ 1492 @Test(expected = UnsupportedOperationException.class) 1493 public void testStartWatchLocalOnlyHotspotNotSupported() { 1494 mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder); 1495 } 1496 1497 /** 1498 * Verify that a call to stopWatchLocalOnlyHotspot is only allowed from callers with the 1499 * signature only NETWORK_SETTINGS permission. 1500 */ 1501 @Test(expected = SecurityException.class) 1502 public void testStopWatchLocalOnlyHotspotNotApprovedCaller() { 1503 doThrow(new SecurityException()).when(mContext) 1504 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), 1505 eq("WifiService")); 1506 mWifiServiceImpl.stopWatchLocalOnlyHotspot(); 1507 } 1508 1509 /** 1510 * Verify that the call to stopWatchLocalOnlyHotspot throws the UnsupportedOperationException 1511 * until the implementation is complete. 1512 */ 1513 @Test(expected = UnsupportedOperationException.class) 1514 public void testStopWatchLocalOnlyHotspotNotSupported() { 1515 mWifiServiceImpl.stopWatchLocalOnlyHotspot(); 1516 } 1517 1518 /** 1519 * Verify that the call to addOrUpdateNetwork for installing Passpoint profile is redirected 1520 * to the Passpoint specific API addOrUpdatePasspointConfiguration. 1521 */ 1522 @Test 1523 public void testAddPasspointProfileViaAddNetwork() throws Exception { 1524 WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork(); 1525 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1526 when(mResources.getBoolean(com.android.internal.R.bool.config_wifi_hotspot2_enabled)) 1527 .thenReturn(true); 1528 1529 when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(), 1530 any(PasspointConfiguration.class), anyInt())).thenReturn(true); 1531 assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config)); 1532 verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(), 1533 any(PasspointConfiguration.class), anyInt()); 1534 reset(mWifiStateMachine); 1535 1536 when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(), 1537 any(PasspointConfiguration.class), anyInt())).thenReturn(false); 1538 assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config)); 1539 verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(), 1540 any(PasspointConfiguration.class), anyInt()); 1541 } 1542} 1543