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