1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.wifi;
18 
19 import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
20 import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
21 import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
22 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
23 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
24 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
25 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
26 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
27 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
28 import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
29 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
30 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
31 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
32 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
33 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
34 
35 import static org.junit.Assert.assertEquals;
36 import static org.junit.Assert.assertFalse;
37 import static org.junit.Assert.assertNotNull;
38 import static org.junit.Assert.assertNull;
39 import static org.junit.Assert.assertTrue;
40 import static org.junit.Assert.fail;
41 import static org.mockito.Mockito.*;
42 
43 import android.content.Context;
44 import android.content.pm.ApplicationInfo;
45 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
46 import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
47 import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
48 import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
49 import android.net.wifi.WifiManager.SoftApCallback;
50 import android.os.Handler;
51 import android.os.IBinder;
52 import android.os.Message;
53 import android.os.Messenger;
54 import android.os.test.TestLooper;
55 import android.support.test.filters.SmallTest;
56 
57 import org.junit.Before;
58 import org.junit.Test;
59 import org.mockito.ArgumentCaptor;
60 import org.mockito.Mock;
61 import org.mockito.MockitoAnnotations;
62 
63 /**
64  * Unit tests for {@link android.net.wifi.WifiManager}.
65  */
66 @SmallTest
67 public class WifiManagerTest {
68 
69     private static final int ERROR_NOT_SET = -1;
70     private static final int ERROR_TEST_REASON = 5;
71     private static final String TEST_PACKAGE_NAME = "TestPackage";
72     private static final String TEST_COUNTRY_CODE = "US";
73 
74     @Mock Context mContext;
75     @Mock IWifiManager mWifiService;
76     @Mock ApplicationInfo mApplicationInfo;
77     @Mock WifiConfiguration mApConfig;
78     @Mock IBinder mAppBinder;
79     @Mock SoftApCallback mSoftApCallback;
80 
81     private Handler mHandler;
82     private TestLooper mLooper;
83     private WifiManager mWifiManager;
84     private Messenger mWifiServiceMessenger;
85     final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class);
86 
setUp()87     @Before public void setUp() throws Exception {
88         MockitoAnnotations.initMocks(this);
89         mLooper = new TestLooper();
90         mHandler = spy(new Handler(mLooper.getLooper()));
91         when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
92         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
93 
94         mWifiServiceMessenger = new Messenger(mHandler);
95         mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
96     }
97 
98     /**
99      * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
100      * WifiConfiguration.  Verify that the return value is propagated to the caller.
101      */
102     @Test
testStartSoftApCallsServiceWithWifiConfig()103     public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
104         when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
105         assertTrue(mWifiManager.startSoftAp(mApConfig));
106 
107         when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
108         assertFalse(mWifiManager.startSoftAp(mApConfig));
109     }
110 
111     /**
112      * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
113      * that the return value is propagated to the caller.
114      */
115     @Test
testStartSoftApCallsServiceWithNullConfig()116     public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
117         when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
118         assertTrue(mWifiManager.startSoftAp(null));
119 
120         when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
121         assertFalse(mWifiManager.startSoftAp(null));
122     }
123 
124     /**
125      * Check the call to stopSoftAp calls WifiService to stopSoftAp.
126      */
127     @Test
testStopSoftApCallsService()128     public void testStopSoftApCallsService() throws Exception {
129         when(mWifiService.stopSoftAp()).thenReturn(true);
130         assertTrue(mWifiManager.stopSoftAp());
131 
132         when(mWifiService.stopSoftAp()).thenReturn(false);
133         assertFalse(mWifiManager.stopSoftAp());
134     }
135 
136     /**
137      * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
138      * WifiService.stopLocalOnlyHotspot.
139      */
140     @Test
testCreationAndCloseOfLocalOnlyHotspotReservation()141     public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
142         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
143         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
144                 anyString())).thenReturn(REQUEST_REGISTERED);
145         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
146 
147         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
148 
149         assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
150         callback.mRes.close();
151         verify(mWifiService).stopLocalOnlyHotspot();
152     }
153 
154     /**
155      * Verify stopLOHS is called when try-with-resources is used properly.
156      */
157     @Test
testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()158     public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
159             throws Exception {
160         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
161         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
162                 anyString())).thenReturn(REQUEST_REGISTERED);
163         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
164 
165         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
166 
167         try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
168             assertEquals(mApConfig, res.getWifiConfiguration());
169         }
170 
171         verify(mWifiService).stopLocalOnlyHotspot();
172     }
173 
174     /**
175      * Test creation of a LocalOnlyHotspotSubscription.
176      * TODO: when registrations are tracked, verify removal on close.
177      */
178     @Test
testCreationOfLocalOnlyHotspotSubscription()179     public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
180         try (WifiManager.LocalOnlyHotspotSubscription sub =
181                 mWifiManager.new LocalOnlyHotspotSubscription()) {
182             sub.close();
183         }
184     }
185 
186     public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
187         public boolean mOnStartedCalled = false;
188         public boolean mOnStoppedCalled = false;
189         public int mFailureReason = -1;
190         public LocalOnlyHotspotReservation mRes = null;
191         public long mCallingThreadId = -1;
192 
193         @Override
onStarted(LocalOnlyHotspotReservation r)194         public void onStarted(LocalOnlyHotspotReservation r) {
195             mRes = r;
196             mOnStartedCalled = true;
197             mCallingThreadId = Thread.currentThread().getId();
198         }
199 
200         @Override
onStopped()201         public void onStopped() {
202             mOnStoppedCalled = true;
203             mCallingThreadId = Thread.currentThread().getId();
204         }
205 
206         @Override
onFailed(int reason)207         public void onFailed(int reason) {
208             mFailureReason = reason;
209             mCallingThreadId = Thread.currentThread().getId();
210         }
211     }
212 
213     /**
214      * Verify callback is properly plumbed when called.
215      */
216     @Test
testLocalOnlyHotspotCallback()217     public void testLocalOnlyHotspotCallback() {
218         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
219         assertFalse(callback.mOnStartedCalled);
220         assertFalse(callback.mOnStoppedCalled);
221         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
222         assertEquals(null, callback.mRes);
223 
224         // test onStarted
225         WifiManager.LocalOnlyHotspotReservation res =
226                 mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
227         callback.onStarted(res);
228         assertEquals(res, callback.mRes);
229         assertTrue(callback.mOnStartedCalled);
230         assertFalse(callback.mOnStoppedCalled);
231         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
232 
233         // test onStopped
234         callback.onStopped();
235         assertEquals(res, callback.mRes);
236         assertTrue(callback.mOnStartedCalled);
237         assertTrue(callback.mOnStoppedCalled);
238         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
239 
240         // test onFailed
241         callback.onFailed(ERROR_TEST_REASON);
242         assertEquals(res, callback.mRes);
243         assertTrue(callback.mOnStartedCalled);
244         assertTrue(callback.mOnStoppedCalled);
245         assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
246     }
247 
248     public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
249         public boolean mOnRegistered = false;
250         public boolean mOnStartedCalled = false;
251         public boolean mOnStoppedCalled = false;
252         public WifiConfiguration mConfig = null;
253         public LocalOnlyHotspotSubscription mSub = null;
254         public long mCallingThreadId = -1;
255 
256         @Override
onRegistered(LocalOnlyHotspotSubscription sub)257         public void onRegistered(LocalOnlyHotspotSubscription sub) {
258             mOnRegistered = true;
259             mSub = sub;
260             mCallingThreadId = Thread.currentThread().getId();
261         }
262 
263         @Override
onStarted(WifiConfiguration config)264         public void onStarted(WifiConfiguration config) {
265             mOnStartedCalled = true;
266             mConfig = config;
267             mCallingThreadId = Thread.currentThread().getId();
268         }
269 
270         @Override
onStopped()271         public void onStopped() {
272             mOnStoppedCalled = true;
273             mCallingThreadId = Thread.currentThread().getId();
274         }
275     }
276 
277     /**
278      * Verify observer is properly plumbed when called.
279      */
280     @Test
testLocalOnlyHotspotObserver()281     public void testLocalOnlyHotspotObserver() {
282         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
283         assertFalse(observer.mOnRegistered);
284         assertFalse(observer.mOnStartedCalled);
285         assertFalse(observer.mOnStoppedCalled);
286         assertEquals(null, observer.mConfig);
287         assertEquals(null, observer.mSub);
288 
289         WifiManager.LocalOnlyHotspotSubscription sub =
290                 mWifiManager.new LocalOnlyHotspotSubscription();
291         observer.onRegistered(sub);
292         assertTrue(observer.mOnRegistered);
293         assertFalse(observer.mOnStartedCalled);
294         assertFalse(observer.mOnStoppedCalled);
295         assertEquals(null, observer.mConfig);
296         assertEquals(sub, observer.mSub);
297 
298         observer.onStarted(mApConfig);
299         assertTrue(observer.mOnRegistered);
300         assertTrue(observer.mOnStartedCalled);
301         assertFalse(observer.mOnStoppedCalled);
302         assertEquals(mApConfig, observer.mConfig);
303         assertEquals(sub, observer.mSub);
304 
305         observer.onStopped();
306         assertTrue(observer.mOnRegistered);
307         assertTrue(observer.mOnStartedCalled);
308         assertTrue(observer.mOnStoppedCalled);
309         assertEquals(mApConfig, observer.mConfig);
310         assertEquals(sub, observer.mSub);
311     }
312 
313     /**
314      * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
315      */
316     @Test
testStartLocalOnlyHotspot()317     public void testStartLocalOnlyHotspot() throws Exception {
318         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
319         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
320 
321         verify(mWifiService)
322                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
323     }
324 
325     /**
326      * Verify a SecurityException is thrown for callers without proper permissions for
327      * startLocalOnlyHotspot.
328      */
329     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityException()330     public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
331         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
332         doThrow(new SecurityException()).when(mWifiService)
333                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
334         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
335     }
336 
337     /**
338      * Verify an IllegalStateException is thrown for callers that already have a pending request for
339      * startLocalOnlyHotspot.
340      */
341     @Test(expected = IllegalStateException.class)
testStartLocalOnlyHotspotThrowsIllegalStateException()342     public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
343         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
344         doThrow(new IllegalStateException()).when(mWifiService)
345                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
346         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
347     }
348 
349     /**
350      * Verify that the handler provided by the caller is used for the callbacks.
351      */
352     @Test
testCorrectLooperIsUsedForHandler()353     public void testCorrectLooperIsUsedForHandler() throws Exception {
354         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
355         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
356                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
357         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
358         mLooper.dispatchAll();
359         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
360         verify(mContext, never()).getMainLooper();
361     }
362 
363     /**
364      * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
365      * application.
366      */
367     @Test
testMainLooperIsUsedWhenHandlerNotProvided()368     public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
369         // record thread from looper.getThread and check ids.
370         TestLooper altLooper = new TestLooper();
371         when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
372         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
373         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
374                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
375         mWifiManager.startLocalOnlyHotspot(callback, null);
376         altLooper.dispatchAll();
377         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
378         assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
379         verify(mContext).getMainLooper();
380     }
381 
382     /**
383      * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
384      * message from WifiServiceImpl.
385      */
386     @Test
testOnStartedIsCalledWithReservation()387     public void testOnStartedIsCalledWithReservation() throws Exception {
388         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
389         TestLooper callbackLooper = new TestLooper();
390         Handler callbackHandler = new Handler(callbackLooper.getLooper());
391         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
392                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
393         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
394         callbackLooper.dispatchAll();
395         mLooper.dispatchAll();
396         assertFalse(callback.mOnStartedCalled);
397         assertEquals(null, callback.mRes);
398         // now trigger the callback
399         Message msg = new Message();
400         msg.what = HOTSPOT_STARTED;
401         msg.obj = mApConfig;
402         mMessengerCaptor.getValue().send(msg);
403         mLooper.dispatchAll();
404         callbackLooper.dispatchAll();
405         assertTrue(callback.mOnStartedCalled);
406         assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
407     }
408 
409     /**
410      * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
411      * config.
412      */
413     @Test
testOnStartedIsCalledWithNullConfig()414     public void testOnStartedIsCalledWithNullConfig() throws Exception {
415         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
416         TestLooper callbackLooper = new TestLooper();
417         Handler callbackHandler = new Handler(callbackLooper.getLooper());
418         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
419                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
420         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
421         callbackLooper.dispatchAll();
422         mLooper.dispatchAll();
423         assertFalse(callback.mOnStartedCalled);
424         assertEquals(null, callback.mRes);
425         // now trigger the callback
426         Message msg = new Message();
427         msg.what = HOTSPOT_STARTED;
428         mMessengerCaptor.getValue().send(msg);
429         mLooper.dispatchAll();
430         callbackLooper.dispatchAll();
431         assertFalse(callback.mOnStartedCalled);
432         assertEquals(ERROR_GENERIC, callback.mFailureReason);
433     }
434 
435     /**
436      * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
437      */
438     @Test
testOnStoppedIsCalled()439     public void testOnStoppedIsCalled() throws Exception {
440         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
441         TestLooper callbackLooper = new TestLooper();
442         Handler callbackHandler = new Handler(callbackLooper.getLooper());
443         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
444                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
445         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
446         callbackLooper.dispatchAll();
447         mLooper.dispatchAll();
448         assertFalse(callback.mOnStoppedCalled);
449         // now trigger the callback
450         Message msg = new Message();
451         msg.what = HOTSPOT_STOPPED;
452         mMessengerCaptor.getValue().send(msg);
453         mLooper.dispatchAll();
454         callbackLooper.dispatchAll();
455         assertTrue(callback.mOnStoppedCalled);
456     }
457 
458     /**
459      * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
460      */
461     @Test
testOnFailedIsCalled()462     public void testOnFailedIsCalled() throws Exception {
463         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
464         TestLooper callbackLooper = new TestLooper();
465         Handler callbackHandler = new Handler(callbackLooper.getLooper());
466         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
467                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
468         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
469         callbackLooper.dispatchAll();
470         mLooper.dispatchAll();
471         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
472         // now trigger the callback
473         Message msg = new Message();
474         msg.what = HOTSPOT_FAILED;
475         msg.arg1 = ERROR_NO_CHANNEL;
476         mMessengerCaptor.getValue().send(msg);
477         mLooper.dispatchAll();
478         callbackLooper.dispatchAll();
479         assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
480     }
481 
482     /**
483      * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
484      */
485     @Test
testLocalOnlyHotspotCallbackFullOnIncompatibleMode()486     public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
487         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
488         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
489                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
490         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
491         mLooper.dispatchAll();
492         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
493         assertFalse(callback.mOnStartedCalled);
494         assertFalse(callback.mOnStoppedCalled);
495         assertEquals(null, callback.mRes);
496     }
497 
498     /**
499      * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
500      */
501     @Test
testLocalOnlyHotspotCallbackFullOnTetheringDisallowed()502     public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
503         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
504         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
505                 anyString())).thenReturn(ERROR_TETHERING_DISALLOWED);
506         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
507         mLooper.dispatchAll();
508         assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
509         assertFalse(callback.mOnStartedCalled);
510         assertFalse(callback.mOnStoppedCalled);
511         assertEquals(null, callback.mRes);
512     }
513 
514     /**
515      * Verify a SecurityException resulting from an application without necessary permissions will
516      * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
517      */
518     @Test(expected = SecurityException.class)
testLocalOnlyHotspotCallbackFullOnSecurityException()519     public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
520         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
521         doThrow(new SecurityException()).when(mWifiService)
522                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
523         try {
524             mWifiManager.startLocalOnlyHotspot(callback, mHandler);
525         } catch (SecurityException e) {
526             assertEquals(ERROR_NOT_SET, callback.mFailureReason);
527             assertFalse(callback.mOnStartedCalled);
528             assertFalse(callback.mOnStoppedCalled);
529             assertEquals(null, callback.mRes);
530             throw e;
531         }
532 
533     }
534 
535     /**
536      * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
537      * SoftApMode fails due to a underlying error.
538      */
539     @Test
testLocalOnlyHotspotCallbackFullOnNoChannelError()540     public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
541         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
542         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
543                 anyString())).thenReturn(REQUEST_REGISTERED);
544         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
545         mLooper.dispatchAll();
546         //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
547         assertFalse(callback.mOnStartedCalled);
548         assertFalse(callback.mOnStoppedCalled);
549         assertEquals(null, callback.mRes);
550     }
551 
552     /**
553      * Verify that the call to cancel a LOHS request does call stopLOHS.
554      */
555     @Test
testCancelLocalOnlyHotspotRequestCallsStopOnWifiService()556     public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
557         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
558         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
559                 anyString())).thenReturn(REQUEST_REGISTERED);
560         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
561         mWifiManager.cancelLocalOnlyHotspotRequest();
562         verify(mWifiService).stopLocalOnlyHotspot();
563     }
564 
565     /**
566      * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
567      * callback stored.
568      */
569     @Test
testCancelLocalOnlyHotspotReturnsWithoutExistingRequest()570     public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
571         mWifiManager.cancelLocalOnlyHotspotRequest();
572     }
573 
574     /**
575      * Verify that the callback is not triggered if the LOHS request was already cancelled.
576      */
577     @Test
testCallbackAfterLocalOnlyHotspotWasCancelled()578     public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
579         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
580         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
581                 anyString())).thenReturn(REQUEST_REGISTERED);
582         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
583         mWifiManager.cancelLocalOnlyHotspotRequest();
584         verify(mWifiService).stopLocalOnlyHotspot();
585         mLooper.dispatchAll();
586         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
587         assertFalse(callback.mOnStartedCalled);
588         assertFalse(callback.mOnStoppedCalled);
589         assertEquals(null, callback.mRes);
590     }
591 
592     /**
593      * Verify that calling cancel LOHS request does not crash if an error callback was already
594      * handled.
595      */
596     @Test
testCancelAfterLocalOnlyHotspotCallbackTriggered()597     public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
598         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
599         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
600                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
601         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
602         mLooper.dispatchAll();
603         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
604         assertFalse(callback.mOnStartedCalled);
605         assertFalse(callback.mOnStoppedCalled);
606         assertEquals(null, callback.mRes);
607         mWifiManager.cancelLocalOnlyHotspotRequest();
608         verify(mWifiService, never()).stopLocalOnlyHotspot();
609     }
610 
611     /**
612      * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
613      */
614     @Test
testWatchLocalOnlyHotspot()615     public void testWatchLocalOnlyHotspot() throws Exception {
616         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
617 
618         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
619         verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
620     }
621 
622     /**
623      * Verify a SecurityException is thrown for callers without proper permissions for
624      * startWatchLocalOnlyHotspot.
625      */
626     @Test(expected = SecurityException.class)
testStartWatchLocalOnlyHotspotThrowsSecurityException()627     public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
628         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
629         doThrow(new SecurityException()).when(mWifiService)
630                 .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
631         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
632     }
633 
634     /**
635      * Verify an IllegalStateException is thrown for callers that already have a pending request for
636      * watchLocalOnlyHotspot.
637      */
638     @Test(expected = IllegalStateException.class)
testStartWatchLocalOnlyHotspotThrowsIllegalStateException()639     public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
640         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
641         doThrow(new IllegalStateException()).when(mWifiService)
642                 .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
643         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
644     }
645 
646     /**
647      * Verify an IllegalArgumentException is thrown if callback is not provided.
648      */
649     @Test
registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()650     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
651         try {
652             mWifiManager.registerSoftApCallback(null, mHandler);
653             fail("expected IllegalArgumentException");
654         } catch (IllegalArgumentException expected) {
655         }
656     }
657 
658     /**
659      * Verify an IllegalArgumentException is thrown if callback is not provided.
660      */
661     @Test
unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()662     public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
663         try {
664             mWifiManager.unregisterSoftApCallback(null);
665             fail("expected IllegalArgumentException");
666         } catch (IllegalArgumentException expected) {
667         }
668     }
669 
670     /**
671      * Verify main looper is used when handler is not provided.
672      */
673     @Test
registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler()674     public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() {
675         when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
676         mWifiManager.registerSoftApCallback(mSoftApCallback, null);
677         verify(mContext).getMainLooper();
678     }
679 
680     /**
681      * Verify the call to registerSoftApCallback goes to WifiServiceImpl.
682      */
683     @Test
registerSoftApCallbackCallGoesToWifiServiceImpl()684     public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
685         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
686         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
687                 any(ISoftApCallback.Stub.class), anyInt());
688     }
689 
690     /**
691      * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl.
692      */
693     @Test
unregisterSoftApCallbackCallGoesToWifiServiceImpl()694     public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
695         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
696         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
697         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
698                 any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
699 
700         mWifiManager.unregisterSoftApCallback(mSoftApCallback);
701         verify(mWifiService).unregisterSoftApCallback(eq((int) callbackIdentifier.getValue()));
702     }
703 
704     /*
705      * Verify client provided callback is being called through callback proxy
706      */
707     @Test
softApCallbackProxyCallsOnStateChanged()708     public void softApCallbackProxyCallsOnStateChanged() throws Exception {
709         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
710                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
711         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
712         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
713                 anyInt());
714 
715         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
716         mLooper.dispatchAll();
717         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
718     }
719 
720     /*
721      * Verify client provided callback is being called through callback proxy
722      */
723     @Test
softApCallbackProxyCallsOnNumClientsChanged()724     public void softApCallbackProxyCallsOnNumClientsChanged() throws Exception {
725         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
726                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
727         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
728         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
729                 anyInt());
730 
731         final int testNumClients = 3;
732         callbackCaptor.getValue().onNumClientsChanged(testNumClients);
733         mLooper.dispatchAll();
734         verify(mSoftApCallback).onNumClientsChanged(testNumClients);
735     }
736 
737     /*
738      * Verify client provided callback is being called through callback proxy on multiple events
739      */
740     @Test
softApCallbackProxyCallsOnMultipleUpdates()741     public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
742         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
743                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
744         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
745         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
746                 anyInt());
747 
748         final int testNumClients = 5;
749         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
750         callbackCaptor.getValue().onNumClientsChanged(testNumClients);
751         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
752 
753         mLooper.dispatchAll();
754         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
755         verify(mSoftApCallback).onNumClientsChanged(testNumClients);
756         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
757     }
758 
759     /*
760      * Verify client provided callback is being called on the correct thread
761      */
762     @Test
softApCallbackIsCalledOnCorrectThread()763     public void softApCallbackIsCalledOnCorrectThread() throws Exception {
764         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
765                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
766         TestLooper altLooper = new TestLooper();
767         Handler altHandler = new Handler(altLooper.getLooper());
768         mWifiManager.registerSoftApCallback(mSoftApCallback, altHandler);
769         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
770                 anyInt());
771 
772         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
773         altLooper.dispatchAll();
774         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
775     }
776 
777     /**
778      * Verify that the handler provided by the caller is used for registering soft AP callback.
779      */
780     @Test
testCorrectLooperIsUsedForSoftApCallbackHandler()781     public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
782         mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler);
783         mLooper.dispatchAll();
784         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
785                 any(ISoftApCallback.Stub.class), anyInt());
786         verify(mContext, never()).getMainLooper();
787     }
788 
789     /**
790      * Verify that the handler provided by the caller is used for the observer.
791      */
792     @Test
testCorrectLooperIsUsedForObserverHandler()793     public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
794         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
795         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
796         mLooper.dispatchAll();
797         assertTrue(observer.mOnRegistered);
798         verify(mContext, never()).getMainLooper();
799     }
800 
801     /**
802      * Verify that the main looper's thread is used if a handler is not provided by the requesting
803      * application.
804      */
805     @Test
testMainLooperIsUsedWhenHandlerNotProvidedForObserver()806     public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
807         // record thread from looper.getThread and check ids.
808         TestLooper altLooper = new TestLooper();
809         when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
810         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
811         mWifiManager.watchLocalOnlyHotspot(observer, null);
812         altLooper.dispatchAll();
813         assertTrue(observer.mOnRegistered);
814         assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
815         verify(mContext).getMainLooper();
816     }
817 
818     /**
819      * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
820      * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
821      */
822     @Test
testOnRegisteredIsCalledWithSubscription()823     public void testOnRegisteredIsCalledWithSubscription() throws Exception {
824         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
825         TestLooper observerLooper = new TestLooper();
826         Handler observerHandler = new Handler(observerLooper.getLooper());
827         assertFalse(observer.mOnRegistered);
828         assertEquals(null, observer.mSub);
829         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
830         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
831                   any(IBinder.class));
832         // now trigger the callback
833         observerLooper.dispatchAll();
834         mLooper.dispatchAll();
835         assertTrue(observer.mOnRegistered);
836         assertNotNull(observer.mSub);
837     }
838 
839     /**
840      * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
841      * HOTSPOT_STARTED message from WifiServiceImpl.
842      */
843     @Test
testObserverOnStartedIsCalledWithWifiConfig()844     public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
845         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
846         TestLooper observerLooper = new TestLooper();
847         Handler observerHandler = new Handler(observerLooper.getLooper());
848         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
849         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
850                   any(IBinder.class));
851         observerLooper.dispatchAll();
852         mLooper.dispatchAll();
853         assertFalse(observer.mOnStartedCalled);
854         // now trigger the callback
855         Message msg = new Message();
856         msg.what = HOTSPOT_STARTED;
857         msg.obj = mApConfig;
858         mMessengerCaptor.getValue().send(msg);
859         mLooper.dispatchAll();
860         observerLooper.dispatchAll();
861         assertTrue(observer.mOnStartedCalled);
862         assertEquals(mApConfig, observer.mConfig);
863     }
864 
865     /**
866      * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
867      * HOTSPOT_STARTED message from WifiServiceImpl with a null config.
868      */
869     @Test
testObserverOnStartedNotCalledWithNullConfig()870     public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
871         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
872         TestLooper observerLooper = new TestLooper();
873         Handler observerHandler = new Handler(observerLooper.getLooper());
874         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
875         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
876                   any(IBinder.class));
877         observerLooper.dispatchAll();
878         mLooper.dispatchAll();
879         assertFalse(observer.mOnStartedCalled);
880         // now trigger the callback
881         Message msg = new Message();
882         msg.what = HOTSPOT_STARTED;
883         mMessengerCaptor.getValue().send(msg);
884         mLooper.dispatchAll();
885         observerLooper.dispatchAll();
886         assertFalse(observer.mOnStartedCalled);
887         assertEquals(null, observer.mConfig);
888     }
889 
890 
891     /**
892      * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
893      * HOTSPOT_STOPPED message from WifiServiceImpl.
894      */
895     @Test
testObserverOnStoppedIsCalled()896     public void testObserverOnStoppedIsCalled() throws Exception {
897         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
898         TestLooper observerLooper = new TestLooper();
899         Handler observerHandler = new Handler(observerLooper.getLooper());
900         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
901         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
902                   any(IBinder.class));
903         observerLooper.dispatchAll();
904         mLooper.dispatchAll();
905         assertFalse(observer.mOnStoppedCalled);
906         // now trigger the callback
907         Message msg = new Message();
908         msg.what = HOTSPOT_STOPPED;
909         mMessengerCaptor.getValue().send(msg);
910         mLooper.dispatchAll();
911         observerLooper.dispatchAll();
912         assertTrue(observer.mOnStoppedCalled);
913     }
914 
915     /**
916      * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
917      */
918     @Test
testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver()919     public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
920         mWifiManager.unregisterLocalOnlyHotspotObserver();
921         verifyZeroInteractions(mWifiService);
922     }
923 
924     /**
925      * Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
926      */
927     @Test
testUnregisterWifiServiceImplCalledWithRegisteredObserver()928     public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
929         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
930         TestLooper observerLooper = new TestLooper();
931         Handler observerHandler = new Handler(observerLooper.getLooper());
932         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
933         mWifiManager.unregisterLocalOnlyHotspotObserver();
934         verify(mWifiService).stopWatchLocalOnlyHotspot();
935     }
936 
937     /**
938      * Verify that calls WifiServiceImpl to set country code when no exception happens.
939      */
940     @Test
testSetWifiCountryCode()941     public void testSetWifiCountryCode() throws Exception {
942         mWifiManager.setCountryCode(TEST_COUNTRY_CODE);
943         verify(mWifiService).setCountryCode(TEST_COUNTRY_CODE);
944     }
945 
946     /**
947      * Verify that WifiManager.setCountryCode() rethrows exceptions if caller does not
948      * have necessary permissions.
949      */
950     @Test(expected = SecurityException.class)
testSetWifiCountryCodeFailedOnSecurityException()951     public void testSetWifiCountryCodeFailedOnSecurityException() throws Exception {
952         doThrow(new SecurityException()).when(mWifiService).setCountryCode(anyString());
953         mWifiManager.setCountryCode(TEST_COUNTRY_CODE);
954     }
955 
956     /**
957      * Test that calls to get the current WPS config token return null and do not have any
958      * interactions with WifiServiceImpl.
959      */
960     @Test
testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull()961     public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() {
962         assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken());
963         verifyNoMoreInteractions(mWifiService);
964     }
965 
966 
967     class WpsCallbackTester extends WifiManager.WpsCallback {
968         public boolean mStarted = false;
969         public boolean mSucceeded = false;
970         public boolean mFailed = false;
971         public int mFailureCode = -1;
972 
973         @Override
onStarted(String pin)974         public void onStarted(String pin) {
975             mStarted = true;
976         }
977 
978         @Override
onSucceeded()979         public void onSucceeded() {
980             mSucceeded = true;
981         }
982 
983         @Override
onFailed(int reason)984         public void onFailed(int reason) {
985             mFailed = true;
986             mFailureCode = reason;
987         }
988 
989     }
990 
991     /**
992      * Verify that a call to start WPS immediately returns a failure.
993      */
994     @Test
testStartWpsImmediatelyFailsWithCallback()995     public void testStartWpsImmediatelyFailsWithCallback() {
996         WpsCallbackTester wpsCallback = new WpsCallbackTester();
997         mWifiManager.startWps(null, wpsCallback);
998         assertTrue(wpsCallback.mFailed);
999         assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
1000         assertFalse(wpsCallback.mStarted);
1001         assertFalse(wpsCallback.mSucceeded);
1002         verifyNoMoreInteractions(mWifiService);
1003     }
1004 
1005     /**
1006      * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback.
1007      */
1008     @Test
testStartWpsDoesNotCallWifiServiceImpl()1009     public void testStartWpsDoesNotCallWifiServiceImpl() {
1010         mWifiManager.startWps(null, null);
1011         verifyNoMoreInteractions(mWifiService);
1012     }
1013 
1014    /**
1015 i     * Verify that a call to cancel WPS immediately returns a failure.
1016      */
1017     @Test
testCancelWpsImmediatelyFailsWithCallback()1018     public void testCancelWpsImmediatelyFailsWithCallback() {
1019         WpsCallbackTester wpsCallback = new WpsCallbackTester();
1020         mWifiManager.cancelWps(wpsCallback);
1021         assertTrue(wpsCallback.mFailed);
1022         assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
1023         assertFalse(wpsCallback.mStarted);
1024         assertFalse(wpsCallback.mSucceeded);
1025         verifyNoMoreInteractions(mWifiService);
1026     }
1027 
1028     /**
1029      * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback.
1030      */
1031     @Test
testCancelWpsDoesNotCallWifiServiceImpl()1032     public void testCancelWpsDoesNotCallWifiServiceImpl() {
1033         mWifiManager.cancelWps(null);
1034         verifyNoMoreInteractions(mWifiService);
1035     }
1036 
1037     /**
1038      * Verify that a successful call properly returns true.
1039      */
1040     @Test
testSetWifiApConfigurationSuccessReturnsTrue()1041     public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception {
1042         WifiConfiguration apConfig = new WifiConfiguration();
1043 
1044         when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
1045                 .thenReturn(true);
1046         assertTrue(mWifiManager.setWifiApConfiguration(apConfig));
1047     }
1048 
1049     /**
1050      * Verify that a failed call properly returns false.
1051      */
1052     @Test
testSetWifiApConfigurationFailureReturnsFalse()1053     public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception {
1054         WifiConfiguration apConfig = new WifiConfiguration();
1055 
1056         when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
1057                 .thenReturn(false);
1058         assertFalse(mWifiManager.setWifiApConfiguration(apConfig));
1059     }
1060 
1061     /**
1062      * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
1063      */
1064     @Test
testSetWifiApConfigurationRethrowsException()1065     public void testSetWifiApConfigurationRethrowsException() throws Exception {
1066         doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any());
1067 
1068         try {
1069             mWifiManager.setWifiApConfiguration(new WifiConfiguration());
1070             fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
1071         } catch (SecurityException e) { }
1072     }
1073 
1074     /**
1075      * Check the call to startScan calls WifiService.
1076      */
1077     @Test
testStartScan()1078     public void testStartScan() throws Exception {
1079         when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(true);
1080         assertTrue(mWifiManager.startScan());
1081 
1082         when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(false);
1083         assertFalse(mWifiManager.startScan());
1084     }
1085 }
1086