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