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.WIFI_AP_STATE_ENABLED;
29 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
30 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
31 
32 import static org.junit.Assert.assertArrayEquals;
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertFalse;
35 import static org.junit.Assert.assertNotNull;
36 import static org.junit.Assert.assertNull;
37 import static org.junit.Assert.assertTrue;
38 import static org.junit.Assert.fail;
39 import static org.mockito.ArgumentMatchers.anyBoolean;
40 import static org.mockito.Mockito.any;
41 import static org.mockito.Mockito.anyInt;
42 import static org.mockito.Mockito.anyList;
43 import static org.mockito.Mockito.anyString;
44 import static org.mockito.Mockito.doThrow;
45 import static org.mockito.Mockito.eq;
46 import static org.mockito.Mockito.inOrder;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.never;
49 import static org.mockito.Mockito.spy;
50 import static org.mockito.Mockito.verify;
51 import static org.mockito.Mockito.verifyNoMoreInteractions;
52 import static org.mockito.Mockito.verifyZeroInteractions;
53 import static org.mockito.Mockito.when;
54 
55 import android.content.Context;
56 import android.content.pm.ApplicationInfo;
57 import android.net.DhcpInfo;
58 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
59 import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
60 import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
61 import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
62 import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
63 import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
64 import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
65 import android.net.wifi.WifiManager.SoftApCallback;
66 import android.net.wifi.WifiManager.TrafficStateCallback;
67 import android.os.Build;
68 import android.os.Handler;
69 import android.os.HandlerExecutor;
70 import android.os.IBinder;
71 import android.os.Message;
72 import android.os.Messenger;
73 import android.os.test.TestLooper;
74 
75 import androidx.test.filters.SmallTest;
76 
77 import org.junit.Before;
78 import org.junit.Test;
79 import org.mockito.ArgumentCaptor;
80 import org.mockito.InOrder;
81 import org.mockito.Mock;
82 import org.mockito.MockitoAnnotations;
83 
84 import java.util.ArrayList;
85 import java.util.HashMap;
86 import java.util.List;
87 import java.util.Map;
88 import java.util.concurrent.Executor;
89 
90 /**
91  * Unit tests for {@link android.net.wifi.WifiManager}.
92  */
93 @SmallTest
94 public class WifiManagerTest {
95 
96     private static final int ERROR_NOT_SET = -1;
97     private static final int ERROR_TEST_REASON = 5;
98     private static final int TEST_UID = 14553;
99     private static final int TEST_NETWORK_ID = 143;
100     private static final String TEST_PACKAGE_NAME = "TestPackage";
101     private static final String TEST_COUNTRY_CODE = "US";
102     private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
103 
104     @Mock Context mContext;
105     @Mock android.net.wifi.IWifiManager mWifiService;
106     @Mock ApplicationInfo mApplicationInfo;
107     @Mock WifiConfiguration mApConfig;
108     @Mock IBinder mAppBinder;
109     @Mock SoftApCallback mSoftApCallback;
110     @Mock TrafficStateCallback mTrafficStateCallback;
111     @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
112     @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
113 
114     private Executor mExecutor;
115     private Handler mHandler;
116     private TestLooper mLooper;
117     private WifiManager mWifiManager;
118     private Messenger mWifiServiceMessenger;
119     final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class);
120 
121     @Before
setUp()122     public void setUp() throws Exception {
123         MockitoAnnotations.initMocks(this);
124         mLooper = new TestLooper();
125         mHandler = spy(new Handler(mLooper.getLooper()));
126         mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
127         when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
128         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
129 
130         mWifiServiceMessenger = new Messenger(mHandler);
131         mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
132         verify(mWifiService).getVerboseLoggingLevel();
133     }
134 
135     /**
136      * Check the call to startSoftAp calls WifiService to startSoftAp with the provided
137      * WifiConfiguration.  Verify that the return value is propagated to the caller.
138      */
139     @Test
testStartSoftApCallsServiceWithWifiConfig()140     public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
141         when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
142         assertTrue(mWifiManager.startSoftAp(mApConfig));
143 
144         when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
145         assertFalse(mWifiManager.startSoftAp(mApConfig));
146     }
147 
148     /**
149      * Check the call to startSoftAp calls WifiService to startSoftAp with a null config.  Verify
150      * that the return value is propagated to the caller.
151      */
152     @Test
testStartSoftApCallsServiceWithNullConfig()153     public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
154         when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
155         assertTrue(mWifiManager.startSoftAp(null));
156 
157         when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
158         assertFalse(mWifiManager.startSoftAp(null));
159     }
160 
161     /**
162      * Check the call to stopSoftAp calls WifiService to stopSoftAp.
163      */
164     @Test
testStopSoftApCallsService()165     public void testStopSoftApCallsService() throws Exception {
166         when(mWifiService.stopSoftAp()).thenReturn(true);
167         assertTrue(mWifiManager.stopSoftAp());
168 
169         when(mWifiService.stopSoftAp()).thenReturn(false);
170         assertFalse(mWifiManager.stopSoftAp());
171     }
172 
173     /**
174      * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
175      * WifiService.stopLocalOnlyHotspot.
176      */
177     @Test
testCreationAndCloseOfLocalOnlyHotspotReservation()178     public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
179         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
180         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
181                 anyString())).thenReturn(REQUEST_REGISTERED);
182         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
183 
184         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
185 
186         assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
187         callback.mRes.close();
188         verify(mWifiService).stopLocalOnlyHotspot();
189     }
190 
191     /**
192      * Verify stopLOHS is called when try-with-resources is used properly.
193      */
194     @Test
testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()195     public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
196             throws Exception {
197         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
198         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
199                 anyString())).thenReturn(REQUEST_REGISTERED);
200         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
201 
202         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
203 
204         try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
205             assertEquals(mApConfig, res.getWifiConfiguration());
206         }
207 
208         verify(mWifiService).stopLocalOnlyHotspot();
209     }
210 
211     /**
212      * Test creation of a LocalOnlyHotspotSubscription.
213      * TODO: when registrations are tracked, verify removal on close.
214      */
215     @Test
testCreationOfLocalOnlyHotspotSubscription()216     public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
217         try (WifiManager.LocalOnlyHotspotSubscription sub =
218                      mWifiManager.new LocalOnlyHotspotSubscription()) {
219             sub.close();
220         }
221     }
222 
223     public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
224         public boolean mOnStartedCalled = false;
225         public boolean mOnStoppedCalled = false;
226         public int mFailureReason = -1;
227         public LocalOnlyHotspotReservation mRes = null;
228         public long mCallingThreadId = -1;
229 
230         @Override
onStarted(LocalOnlyHotspotReservation r)231         public void onStarted(LocalOnlyHotspotReservation r) {
232             mRes = r;
233             mOnStartedCalled = true;
234             mCallingThreadId = Thread.currentThread().getId();
235         }
236 
237         @Override
onStopped()238         public void onStopped() {
239             mOnStoppedCalled = true;
240             mCallingThreadId = Thread.currentThread().getId();
241         }
242 
243         @Override
onFailed(int reason)244         public void onFailed(int reason) {
245             mFailureReason = reason;
246             mCallingThreadId = Thread.currentThread().getId();
247         }
248     }
249 
250     /**
251      * Verify callback is properly plumbed when called.
252      */
253     @Test
testLocalOnlyHotspotCallback()254     public void testLocalOnlyHotspotCallback() {
255         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
256         assertFalse(callback.mOnStartedCalled);
257         assertFalse(callback.mOnStoppedCalled);
258         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
259         assertEquals(null, callback.mRes);
260 
261         // test onStarted
262         WifiManager.LocalOnlyHotspotReservation res =
263                 mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
264         callback.onStarted(res);
265         assertEquals(res, callback.mRes);
266         assertTrue(callback.mOnStartedCalled);
267         assertFalse(callback.mOnStoppedCalled);
268         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
269 
270         // test onStopped
271         callback.onStopped();
272         assertEquals(res, callback.mRes);
273         assertTrue(callback.mOnStartedCalled);
274         assertTrue(callback.mOnStoppedCalled);
275         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
276 
277         // test onFailed
278         callback.onFailed(ERROR_TEST_REASON);
279         assertEquals(res, callback.mRes);
280         assertTrue(callback.mOnStartedCalled);
281         assertTrue(callback.mOnStoppedCalled);
282         assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
283     }
284 
285     public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
286         public boolean mOnRegistered = false;
287         public boolean mOnStartedCalled = false;
288         public boolean mOnStoppedCalled = false;
289         public WifiConfiguration mConfig = null;
290         public LocalOnlyHotspotSubscription mSub = null;
291         public long mCallingThreadId = -1;
292 
293         @Override
onRegistered(LocalOnlyHotspotSubscription sub)294         public void onRegistered(LocalOnlyHotspotSubscription sub) {
295             mOnRegistered = true;
296             mSub = sub;
297             mCallingThreadId = Thread.currentThread().getId();
298         }
299 
300         @Override
onStarted(WifiConfiguration config)301         public void onStarted(WifiConfiguration config) {
302             mOnStartedCalled = true;
303             mConfig = config;
304             mCallingThreadId = Thread.currentThread().getId();
305         }
306 
307         @Override
onStopped()308         public void onStopped() {
309             mOnStoppedCalled = true;
310             mCallingThreadId = Thread.currentThread().getId();
311         }
312     }
313 
314     /**
315      * Verify observer is properly plumbed when called.
316      */
317     @Test
testLocalOnlyHotspotObserver()318     public void testLocalOnlyHotspotObserver() {
319         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
320         assertFalse(observer.mOnRegistered);
321         assertFalse(observer.mOnStartedCalled);
322         assertFalse(observer.mOnStoppedCalled);
323         assertEquals(null, observer.mConfig);
324         assertEquals(null, observer.mSub);
325 
326         WifiManager.LocalOnlyHotspotSubscription sub =
327                 mWifiManager.new LocalOnlyHotspotSubscription();
328         observer.onRegistered(sub);
329         assertTrue(observer.mOnRegistered);
330         assertFalse(observer.mOnStartedCalled);
331         assertFalse(observer.mOnStoppedCalled);
332         assertEquals(null, observer.mConfig);
333         assertEquals(sub, observer.mSub);
334 
335         observer.onStarted(mApConfig);
336         assertTrue(observer.mOnRegistered);
337         assertTrue(observer.mOnStartedCalled);
338         assertFalse(observer.mOnStoppedCalled);
339         assertEquals(mApConfig, observer.mConfig);
340         assertEquals(sub, observer.mSub);
341 
342         observer.onStopped();
343         assertTrue(observer.mOnRegistered);
344         assertTrue(observer.mOnStartedCalled);
345         assertTrue(observer.mOnStoppedCalled);
346         assertEquals(mApConfig, observer.mConfig);
347         assertEquals(sub, observer.mSub);
348     }
349 
350     /**
351      * Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
352      */
353     @Test
testStartLocalOnlyHotspot()354     public void testStartLocalOnlyHotspot() throws Exception {
355         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
356         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
357 
358         verify(mWifiService)
359                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
360     }
361 
362     /**
363      * Verify a SecurityException is thrown for callers without proper permissions for
364      * startLocalOnlyHotspot.
365      */
366     @Test(expected = SecurityException.class)
testStartLocalOnlyHotspotThrowsSecurityException()367     public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
368         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
369         doThrow(new SecurityException()).when(mWifiService)
370                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
371         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
372     }
373 
374     /**
375      * Verify an IllegalStateException is thrown for callers that already have a pending request for
376      * startLocalOnlyHotspot.
377      */
378     @Test(expected = IllegalStateException.class)
testStartLocalOnlyHotspotThrowsIllegalStateException()379     public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
380         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
381         doThrow(new IllegalStateException()).when(mWifiService)
382                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
383         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
384     }
385 
386     /**
387      * Verify that the handler provided by the caller is used for the callbacks.
388      */
389     @Test
testCorrectLooperIsUsedForHandler()390     public void testCorrectLooperIsUsedForHandler() throws Exception {
391         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
392         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
393                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
394         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
395         mLooper.dispatchAll();
396         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
397         verify(mContext, never()).getMainLooper();
398     }
399 
400     /**
401      * Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
402      * application.
403      */
404     @Test
testMainLooperIsUsedWhenHandlerNotProvided()405     public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
406         // record thread from looper.getThread and check ids.
407         TestLooper altLooper = new TestLooper();
408         when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
409         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
410         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
411                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
412         mWifiManager.startLocalOnlyHotspot(callback, null);
413         altLooper.dispatchAll();
414         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
415         assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
416         verify(mContext).getMainLooper();
417     }
418 
419     /**
420      * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
421      * message from WifiServiceImpl.
422      */
423     @Test
testOnStartedIsCalledWithReservation()424     public void testOnStartedIsCalledWithReservation() throws Exception {
425         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
426         TestLooper callbackLooper = new TestLooper();
427         Handler callbackHandler = new Handler(callbackLooper.getLooper());
428         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
429                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
430         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
431         callbackLooper.dispatchAll();
432         mLooper.dispatchAll();
433         assertFalse(callback.mOnStartedCalled);
434         assertEquals(null, callback.mRes);
435         // now trigger the callback
436         Message msg = new Message();
437         msg.what = HOTSPOT_STARTED;
438         msg.obj = mApConfig;
439         mMessengerCaptor.getValue().send(msg);
440         mLooper.dispatchAll();
441         callbackLooper.dispatchAll();
442         assertTrue(callback.mOnStartedCalled);
443         assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
444     }
445 
446     /**
447      * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
448      * config.
449      */
450     @Test
testOnStartedIsCalledWithNullConfig()451     public void testOnStartedIsCalledWithNullConfig() throws Exception {
452         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
453         TestLooper callbackLooper = new TestLooper();
454         Handler callbackHandler = new Handler(callbackLooper.getLooper());
455         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
456                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
457         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
458         callbackLooper.dispatchAll();
459         mLooper.dispatchAll();
460         assertFalse(callback.mOnStartedCalled);
461         assertEquals(null, callback.mRes);
462         // now trigger the callback
463         Message msg = new Message();
464         msg.what = HOTSPOT_STARTED;
465         mMessengerCaptor.getValue().send(msg);
466         mLooper.dispatchAll();
467         callbackLooper.dispatchAll();
468         assertFalse(callback.mOnStartedCalled);
469         assertEquals(ERROR_GENERIC, callback.mFailureReason);
470     }
471 
472     /**
473      * Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
474      */
475     @Test
testOnStoppedIsCalled()476     public void testOnStoppedIsCalled() throws Exception {
477         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
478         TestLooper callbackLooper = new TestLooper();
479         Handler callbackHandler = new Handler(callbackLooper.getLooper());
480         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
481                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
482         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
483         callbackLooper.dispatchAll();
484         mLooper.dispatchAll();
485         assertFalse(callback.mOnStoppedCalled);
486         // now trigger the callback
487         Message msg = new Message();
488         msg.what = HOTSPOT_STOPPED;
489         mMessengerCaptor.getValue().send(msg);
490         mLooper.dispatchAll();
491         callbackLooper.dispatchAll();
492         assertTrue(callback.mOnStoppedCalled);
493     }
494 
495     /**
496      * Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
497      */
498     @Test
testOnFailedIsCalled()499     public void testOnFailedIsCalled() throws Exception {
500         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
501         TestLooper callbackLooper = new TestLooper();
502         Handler callbackHandler = new Handler(callbackLooper.getLooper());
503         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
504                   any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
505         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
506         callbackLooper.dispatchAll();
507         mLooper.dispatchAll();
508         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
509         // now trigger the callback
510         Message msg = new Message();
511         msg.what = HOTSPOT_FAILED;
512         msg.arg1 = ERROR_NO_CHANNEL;
513         mMessengerCaptor.getValue().send(msg);
514         mLooper.dispatchAll();
515         callbackLooper.dispatchAll();
516         assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
517     }
518 
519     /**
520      * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
521      */
522     @Test
testLocalOnlyHotspotCallbackFullOnIncompatibleMode()523     public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
524         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
525         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
526                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
527         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
528         mLooper.dispatchAll();
529         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
530         assertFalse(callback.mOnStartedCalled);
531         assertFalse(callback.mOnStoppedCalled);
532         assertEquals(null, callback.mRes);
533     }
534 
535     /**
536      * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
537      */
538     @Test
testLocalOnlyHotspotCallbackFullOnTetheringDisallowed()539     public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
540         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
541         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
542                 anyString())).thenReturn(ERROR_TETHERING_DISALLOWED);
543         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
544         mLooper.dispatchAll();
545         assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
546         assertFalse(callback.mOnStartedCalled);
547         assertFalse(callback.mOnStoppedCalled);
548         assertEquals(null, callback.mRes);
549     }
550 
551     /**
552      * Verify a SecurityException resulting from an application without necessary permissions will
553      * bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
554      */
555     @Test(expected = SecurityException.class)
testLocalOnlyHotspotCallbackFullOnSecurityException()556     public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
557         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
558         doThrow(new SecurityException()).when(mWifiService)
559                 .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
560         try {
561             mWifiManager.startLocalOnlyHotspot(callback, mHandler);
562         } catch (SecurityException e) {
563             assertEquals(ERROR_NOT_SET, callback.mFailureReason);
564             assertFalse(callback.mOnStartedCalled);
565             assertFalse(callback.mOnStoppedCalled);
566             assertEquals(null, callback.mRes);
567             throw e;
568         }
569 
570     }
571 
572     /**
573      * Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
574      * SoftApMode fails due to a underlying error.
575      */
576     @Test
testLocalOnlyHotspotCallbackFullOnNoChannelError()577     public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
578         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
579         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
580                 anyString())).thenReturn(REQUEST_REGISTERED);
581         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
582         mLooper.dispatchAll();
583         //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
584         assertFalse(callback.mOnStartedCalled);
585         assertFalse(callback.mOnStoppedCalled);
586         assertEquals(null, callback.mRes);
587     }
588 
589     /**
590      * Verify that the call to cancel a LOHS request does call stopLOHS.
591      */
592     @Test
testCancelLocalOnlyHotspotRequestCallsStopOnWifiService()593     public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
594         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
595         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
596                 anyString())).thenReturn(REQUEST_REGISTERED);
597         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
598         mWifiManager.cancelLocalOnlyHotspotRequest();
599         verify(mWifiService).stopLocalOnlyHotspot();
600     }
601 
602     /**
603      * Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
604      * callback stored.
605      */
606     @Test
testCancelLocalOnlyHotspotReturnsWithoutExistingRequest()607     public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
608         mWifiManager.cancelLocalOnlyHotspotRequest();
609     }
610 
611     /**
612      * Verify that the callback is not triggered if the LOHS request was already cancelled.
613      */
614     @Test
testCallbackAfterLocalOnlyHotspotWasCancelled()615     public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
616         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
617         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
618                 anyString())).thenReturn(REQUEST_REGISTERED);
619         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
620         mWifiManager.cancelLocalOnlyHotspotRequest();
621         verify(mWifiService).stopLocalOnlyHotspot();
622         mLooper.dispatchAll();
623         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
624         assertFalse(callback.mOnStartedCalled);
625         assertFalse(callback.mOnStoppedCalled);
626         assertEquals(null, callback.mRes);
627     }
628 
629     /**
630      * Verify that calling cancel LOHS request does not crash if an error callback was already
631      * handled.
632      */
633     @Test
testCancelAfterLocalOnlyHotspotCallbackTriggered()634     public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
635         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
636         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
637                 anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
638         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
639         mLooper.dispatchAll();
640         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
641         assertFalse(callback.mOnStartedCalled);
642         assertFalse(callback.mOnStoppedCalled);
643         assertEquals(null, callback.mRes);
644         mWifiManager.cancelLocalOnlyHotspotRequest();
645         verify(mWifiService, never()).stopLocalOnlyHotspot();
646     }
647 
648     /**
649      * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
650      */
651     @Test
testWatchLocalOnlyHotspot()652     public void testWatchLocalOnlyHotspot() throws Exception {
653         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
654 
655         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
656         verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
657     }
658 
659     /**
660      * Verify a SecurityException is thrown for callers without proper permissions for
661      * startWatchLocalOnlyHotspot.
662      */
663     @Test(expected = SecurityException.class)
testStartWatchLocalOnlyHotspotThrowsSecurityException()664     public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
665         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
666         doThrow(new SecurityException()).when(mWifiService)
667                 .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
668         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
669     }
670 
671     /**
672      * Verify an IllegalStateException is thrown for callers that already have a pending request for
673      * watchLocalOnlyHotspot.
674      */
675     @Test(expected = IllegalStateException.class)
testStartWatchLocalOnlyHotspotThrowsIllegalStateException()676     public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
677         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
678         doThrow(new IllegalStateException()).when(mWifiService)
679                 .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
680         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
681     }
682 
683     /**
684      * Verify an IllegalArgumentException is thrown if callback is not provided.
685      */
686     @Test
registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()687     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
688         try {
689             mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
690             fail("expected IllegalArgumentException");
691         } catch (IllegalArgumentException expected) {
692         }
693     }
694 
695     /**
696      * Verify an IllegalArgumentException is thrown if executor is null.
697      */
698     @Test
registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor()699     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() {
700         try {
701             mWifiManager.registerSoftApCallback(null, mSoftApCallback);
702             fail("expected IllegalArgumentException");
703         } catch (IllegalArgumentException expected) {
704         }
705     }
706 
707     /**
708      * Verify an IllegalArgumentException is thrown if callback is not provided.
709      */
710     @Test
unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback()711     public void unregisterSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
712         try {
713             mWifiManager.unregisterSoftApCallback(null);
714             fail("expected IllegalArgumentException");
715         } catch (IllegalArgumentException expected) {
716         }
717     }
718 
719     /**
720      * Verify the call to registerSoftApCallback goes to WifiServiceImpl.
721      */
722     @Test
registerSoftApCallbackCallGoesToWifiServiceImpl()723     public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
724         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
725         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
726                 any(ISoftApCallback.Stub.class), anyInt());
727     }
728 
729     /**
730      * Verify the call to unregisterSoftApCallback goes to WifiServiceImpl.
731      */
732     @Test
unregisterSoftApCallbackCallGoesToWifiServiceImpl()733     public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
734         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
735         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
736         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
737                 any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
738 
739         mWifiManager.unregisterSoftApCallback(mSoftApCallback);
740         verify(mWifiService).unregisterSoftApCallback(eq((int) callbackIdentifier.getValue()));
741     }
742 
743     /*
744      * Verify client-provided callback is being called through callback proxy
745      */
746     @Test
softApCallbackProxyCallsOnStateChanged()747     public void softApCallbackProxyCallsOnStateChanged() throws Exception {
748         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
749                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
750         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
751         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
752                 anyInt());
753 
754         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
755         mLooper.dispatchAll();
756         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
757     }
758 
759     /*
760      * Verify client-provided callback is being called through callback proxy
761      */
762     @Test
softApCallbackProxyCallsOnConnectedClientsChanged()763     public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
764         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
765                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
766         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
767         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
768                 anyInt());
769 
770         final List<WifiClient> testClients = new ArrayList();
771         callbackCaptor.getValue().onConnectedClientsChanged(testClients);
772         mLooper.dispatchAll();
773         verify(mSoftApCallback).onConnectedClientsChanged(testClients);
774     }
775 
776     /*
777      * Verify client-provided callback is being called through callback proxy on multiple events
778      */
779     @Test
softApCallbackProxyCallsOnMultipleUpdates()780     public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
781         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
782                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
783         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
784         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
785                 anyInt());
786 
787         final List<WifiClient> testClients = new ArrayList();
788         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
789         callbackCaptor.getValue().onConnectedClientsChanged(testClients);
790         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
791 
792         mLooper.dispatchAll();
793         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
794         verify(mSoftApCallback).onConnectedClientsChanged(testClients);
795         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
796     }
797 
798     /*
799      * Verify client-provided callback is being called on the correct thread
800      */
801     @Test
softApCallbackIsCalledOnCorrectThread()802     public void softApCallbackIsCalledOnCorrectThread() throws Exception {
803         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
804                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
805         TestLooper altLooper = new TestLooper();
806         Handler altHandler = new Handler(altLooper.getLooper());
807         mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
808         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
809                 anyInt());
810 
811         callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
812         altLooper.dispatchAll();
813         verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
814     }
815 
816     /**
817      * Verify that the handler provided by the caller is used for registering soft AP callback.
818      */
819     @Test
testCorrectLooperIsUsedForSoftApCallbackHandler()820     public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
821         mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
822         mLooper.dispatchAll();
823         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
824                 any(ISoftApCallback.Stub.class), anyInt());
825         verify(mContext, never()).getMainLooper();
826     }
827 
828     /**
829      * Verify that the handler provided by the caller is used for the observer.
830      */
831     @Test
testCorrectLooperIsUsedForObserverHandler()832     public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
833         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
834         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
835         mLooper.dispatchAll();
836         assertTrue(observer.mOnRegistered);
837         verify(mContext, never()).getMainLooper();
838     }
839 
840     /**
841      * Verify that the main looper's thread is used if a handler is not provided by the requesting
842      * application.
843      */
844     @Test
testMainLooperIsUsedWhenHandlerNotProvidedForObserver()845     public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
846         // record thread from looper.getThread and check ids.
847         TestLooper altLooper = new TestLooper();
848         when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
849         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
850         mWifiManager.watchLocalOnlyHotspot(observer, null);
851         altLooper.dispatchAll();
852         assertTrue(observer.mOnRegistered);
853         assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
854         verify(mContext).getMainLooper();
855     }
856 
857     /**
858      * Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
859      * HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
860      */
861     @Test
testOnRegisteredIsCalledWithSubscription()862     public void testOnRegisteredIsCalledWithSubscription() throws Exception {
863         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
864         TestLooper observerLooper = new TestLooper();
865         Handler observerHandler = new Handler(observerLooper.getLooper());
866         assertFalse(observer.mOnRegistered);
867         assertEquals(null, observer.mSub);
868         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
869         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
870                   any(IBinder.class));
871         // now trigger the callback
872         observerLooper.dispatchAll();
873         mLooper.dispatchAll();
874         assertTrue(observer.mOnRegistered);
875         assertNotNull(observer.mSub);
876     }
877 
878     /**
879      * Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
880      * HOTSPOT_STARTED message from WifiServiceImpl.
881      */
882     @Test
testObserverOnStartedIsCalledWithWifiConfig()883     public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
884         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
885         TestLooper observerLooper = new TestLooper();
886         Handler observerHandler = new Handler(observerLooper.getLooper());
887         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
888         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
889                   any(IBinder.class));
890         observerLooper.dispatchAll();
891         mLooper.dispatchAll();
892         assertFalse(observer.mOnStartedCalled);
893         // now trigger the callback
894         Message msg = new Message();
895         msg.what = HOTSPOT_STARTED;
896         msg.obj = mApConfig;
897         mMessengerCaptor.getValue().send(msg);
898         mLooper.dispatchAll();
899         observerLooper.dispatchAll();
900         assertTrue(observer.mOnStartedCalled);
901         assertEquals(mApConfig, observer.mConfig);
902     }
903 
904     /**
905      * Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
906      * HOTSPOT_STARTED message from WifiServiceImpl with a null config.
907      */
908     @Test
testObserverOnStartedNotCalledWithNullConfig()909     public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
910         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
911         TestLooper observerLooper = new TestLooper();
912         Handler observerHandler = new Handler(observerLooper.getLooper());
913         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
914         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
915                   any(IBinder.class));
916         observerLooper.dispatchAll();
917         mLooper.dispatchAll();
918         assertFalse(observer.mOnStartedCalled);
919         // now trigger the callback
920         Message msg = new Message();
921         msg.what = HOTSPOT_STARTED;
922         mMessengerCaptor.getValue().send(msg);
923         mLooper.dispatchAll();
924         observerLooper.dispatchAll();
925         assertFalse(observer.mOnStartedCalled);
926         assertEquals(null, observer.mConfig);
927     }
928 
929 
930     /**
931      * Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
932      * HOTSPOT_STOPPED message from WifiServiceImpl.
933      */
934     @Test
testObserverOnStoppedIsCalled()935     public void testObserverOnStoppedIsCalled() throws Exception {
936         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
937         TestLooper observerLooper = new TestLooper();
938         Handler observerHandler = new Handler(observerLooper.getLooper());
939         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
940         verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
941                   any(IBinder.class));
942         observerLooper.dispatchAll();
943         mLooper.dispatchAll();
944         assertFalse(observer.mOnStoppedCalled);
945         // now trigger the callback
946         Message msg = new Message();
947         msg.what = HOTSPOT_STOPPED;
948         mMessengerCaptor.getValue().send(msg);
949         mLooper.dispatchAll();
950         observerLooper.dispatchAll();
951         assertTrue(observer.mOnStoppedCalled);
952     }
953 
954     /**
955      * Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
956      */
957     @Test
testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver()958     public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
959         mWifiManager.unregisterLocalOnlyHotspotObserver();
960         verifyZeroInteractions(mWifiService);
961     }
962 
963     /**
964      * Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
965      */
966     @Test
testUnregisterWifiServiceImplCalledWithRegisteredObserver()967     public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
968         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
969         TestLooper observerLooper = new TestLooper();
970         Handler observerHandler = new Handler(observerLooper.getLooper());
971         mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
972         mWifiManager.unregisterLocalOnlyHotspotObserver();
973         verify(mWifiService).stopWatchLocalOnlyHotspot();
974     }
975 
976     /**
977      * Verify that calls WifiServiceImpl to set country code when no exception happens.
978      */
979     @Test
testSetWifiCountryCode()980     public void testSetWifiCountryCode() throws Exception {
981         mWifiManager.setCountryCode(TEST_COUNTRY_CODE);
982         verify(mWifiService).setCountryCode(TEST_COUNTRY_CODE);
983     }
984 
985     /**
986      * Verify that WifiManager.setCountryCode() rethrows exceptions if caller does not
987      * have necessary permissions.
988      */
989     @Test(expected = SecurityException.class)
testSetWifiCountryCodeFailedOnSecurityException()990     public void testSetWifiCountryCodeFailedOnSecurityException() throws Exception {
991         doThrow(new SecurityException()).when(mWifiService).setCountryCode(anyString());
992         mWifiManager.setCountryCode(TEST_COUNTRY_CODE);
993     }
994 
995     /**
996      * Test that calls to get the current WPS config token return null and do not have any
997      * interactions with WifiServiceImpl.
998      */
999     @Test
testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull()1000     public void testGetCurrentNetworkWpsNfcConfigurationTokenReturnsNull() {
1001         assertNull(mWifiManager.getCurrentNetworkWpsNfcConfigurationToken());
1002         verifyNoMoreInteractions(mWifiService);
1003     }
1004 
1005 
1006     class WpsCallbackTester extends WifiManager.WpsCallback {
1007         public boolean mStarted = false;
1008         public boolean mSucceeded = false;
1009         public boolean mFailed = false;
1010         public int mFailureCode = -1;
1011 
1012         @Override
onStarted(String pin)1013         public void onStarted(String pin) {
1014             mStarted = true;
1015         }
1016 
1017         @Override
onSucceeded()1018         public void onSucceeded() {
1019             mSucceeded = true;
1020         }
1021 
1022         @Override
onFailed(int reason)1023         public void onFailed(int reason) {
1024             mFailed = true;
1025             mFailureCode = reason;
1026         }
1027 
1028     }
1029 
1030     /**
1031      * Verify that a call to start WPS immediately returns a failure.
1032      */
1033     @Test
testStartWpsImmediatelyFailsWithCallback()1034     public void testStartWpsImmediatelyFailsWithCallback() {
1035         WpsCallbackTester wpsCallback = new WpsCallbackTester();
1036         mWifiManager.startWps(null, wpsCallback);
1037         assertTrue(wpsCallback.mFailed);
1038         assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
1039         assertFalse(wpsCallback.mStarted);
1040         assertFalse(wpsCallback.mSucceeded);
1041         verifyNoMoreInteractions(mWifiService);
1042     }
1043 
1044     /**
1045      * Verify that a call to start WPS does not go to WifiServiceImpl if we do not have a callback.
1046      */
1047     @Test
testStartWpsDoesNotCallWifiServiceImpl()1048     public void testStartWpsDoesNotCallWifiServiceImpl() {
1049         mWifiManager.startWps(null, null);
1050         verifyNoMoreInteractions(mWifiService);
1051     }
1052 
1053     /**
1054      * Verify that a call to cancel WPS immediately returns a failure.
1055      */
1056     @Test
testCancelWpsImmediatelyFailsWithCallback()1057     public void testCancelWpsImmediatelyFailsWithCallback() {
1058         WpsCallbackTester wpsCallback = new WpsCallbackTester();
1059         mWifiManager.cancelWps(wpsCallback);
1060         assertTrue(wpsCallback.mFailed);
1061         assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
1062         assertFalse(wpsCallback.mStarted);
1063         assertFalse(wpsCallback.mSucceeded);
1064         verifyNoMoreInteractions(mWifiService);
1065     }
1066 
1067     /**
1068      * Verify that a call to cancel WPS does not go to WifiServiceImpl if we do not have a callback.
1069      */
1070     @Test
testCancelWpsDoesNotCallWifiServiceImpl()1071     public void testCancelWpsDoesNotCallWifiServiceImpl() {
1072         mWifiManager.cancelWps(null);
1073         verifyNoMoreInteractions(mWifiService);
1074     }
1075 
1076     /**
1077      * Verify that a successful call properly returns true.
1078      */
1079     @Test
testSetWifiApConfigurationSuccessReturnsTrue()1080     public void testSetWifiApConfigurationSuccessReturnsTrue() throws Exception {
1081         WifiConfiguration apConfig = new WifiConfiguration();
1082 
1083         when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
1084                 .thenReturn(true);
1085         assertTrue(mWifiManager.setWifiApConfiguration(apConfig));
1086     }
1087 
1088     /**
1089      * Verify that a failed call properly returns false.
1090      */
1091     @Test
testSetWifiApConfigurationFailureReturnsFalse()1092     public void testSetWifiApConfigurationFailureReturnsFalse() throws Exception {
1093         WifiConfiguration apConfig = new WifiConfiguration();
1094 
1095         when(mWifiService.setWifiApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
1096                 .thenReturn(false);
1097         assertFalse(mWifiManager.setWifiApConfiguration(apConfig));
1098     }
1099 
1100     /**
1101      * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions.
1102      */
1103     @Test
testSetWifiApConfigurationRethrowsException()1104     public void testSetWifiApConfigurationRethrowsException() throws Exception {
1105         doThrow(new SecurityException()).when(mWifiService).setWifiApConfiguration(any(), any());
1106 
1107         try {
1108             mWifiManager.setWifiApConfiguration(new WifiConfiguration());
1109             fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
1110         } catch (SecurityException e) { }
1111     }
1112 
1113     /**
1114      * Check the call to startScan calls WifiService.
1115      */
1116     @Test
testStartScan()1117     public void testStartScan() throws Exception {
1118         when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(true);
1119         assertTrue(mWifiManager.startScan());
1120 
1121         when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(false);
1122         assertFalse(mWifiManager.startScan());
1123     }
1124 
1125     /**
1126      * Verify main looper is used when handler is not provided.
1127      */
1128     @Test
registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()1129     public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()
1130             throws Exception {
1131         when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
1132         ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
1133                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
1134         mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, null);
1135         verify(mWifiService).registerTrafficStateCallback(
1136                 any(IBinder.class), callbackCaptor.capture(), anyInt());
1137 
1138         assertEquals(0, mLooper.dispatchAll());
1139         callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
1140         assertEquals(1, mLooper.dispatchAll());
1141         verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
1142     }
1143 
1144     /**
1145      * Verify the call to unregisterTrafficStateCallback goes to WifiServiceImpl.
1146      */
1147     @Test
unregisterTrafficStateCallbackCallGoesToWifiServiceImpl()1148     public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception {
1149         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
1150         mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler);
1151         verify(mWifiService).registerTrafficStateCallback(any(IBinder.class),
1152                 any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture());
1153 
1154         mWifiManager.unregisterTrafficStateCallback(mTrafficStateCallback);
1155         verify(mWifiService).unregisterTrafficStateCallback(
1156                 eq((int) callbackIdentifier.getValue()));
1157     }
1158 
1159     /*
1160      * Verify client-provided callback is being called through callback proxy on multiple events
1161      */
1162     @Test
trafficStateCallbackProxyCallsOnMultipleUpdates()1163     public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception {
1164         ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
1165                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
1166         mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler);
1167         verify(mWifiService).registerTrafficStateCallback(
1168                 any(IBinder.class), callbackCaptor.capture(), anyInt());
1169 
1170         InOrder inOrder = inOrder(mTrafficStateCallback);
1171 
1172         callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN);
1173         callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
1174         callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT);
1175 
1176         mLooper.dispatchAll();
1177         inOrder.verify(mTrafficStateCallback).onStateChanged(
1178                 TrafficStateCallback.DATA_ACTIVITY_IN);
1179         inOrder.verify(mTrafficStateCallback).onStateChanged(
1180                 TrafficStateCallback.DATA_ACTIVITY_INOUT);
1181         inOrder.verify(mTrafficStateCallback).onStateChanged(
1182                 TrafficStateCallback.DATA_ACTIVITY_OUT);
1183     }
1184 
1185     /*
1186      * Verify client-provided callback is being called on the correct thread
1187      */
1188     @Test
trafficStateCallbackIsCalledOnCorrectThread()1189     public void trafficStateCallbackIsCalledOnCorrectThread() throws Exception {
1190         ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
1191                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
1192         TestLooper altLooper = new TestLooper();
1193         Handler altHandler = new Handler(altLooper.getLooper());
1194         mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler);
1195         verify(mContext, never()).getMainLooper();
1196         verify(mWifiService).registerTrafficStateCallback(
1197                 any(IBinder.class), callbackCaptor.capture(), anyInt());
1198 
1199         assertEquals(0, altLooper.dispatchAll());
1200         callbackCaptor.getValue().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
1201         assertEquals(1, altLooper.dispatchAll());
1202         verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
1203     }
1204 
1205     /**
1206      * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
1207      */
1208     @Test
registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()1209     public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
1210             throws Exception {
1211         when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
1212         ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
1213                 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
1214         mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
1215         verify(mWifiService).registerNetworkRequestMatchCallback(
1216                 any(IBinder.class), callbackCaptor.capture(), anyInt());
1217 
1218         INetworkRequestUserSelectionCallback iUserSelectionCallback =
1219                 mock(INetworkRequestUserSelectionCallback.class);
1220 
1221         assertEquals(0, mLooper.dispatchAll());
1222 
1223         callbackCaptor.getValue().onAbort();
1224         assertEquals(1, mLooper.dispatchAll());
1225         verify(mNetworkRequestMatchCallback).onAbort();
1226 
1227         callbackCaptor.getValue().onMatch(new ArrayList<ScanResult>());
1228         assertEquals(1, mLooper.dispatchAll());
1229         verify(mNetworkRequestMatchCallback).onMatch(anyList());
1230 
1231         callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
1232         assertEquals(1, mLooper.dispatchAll());
1233         verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
1234                 any(WifiConfiguration.class));
1235 
1236         callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
1237         assertEquals(1, mLooper.dispatchAll());
1238         verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
1239                 any(WifiConfiguration.class));
1240     }
1241 
1242     /**
1243      * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
1244      */
1245     @Test
unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()1246     public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
1247         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
1248         mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler);
1249         verify(mWifiService).registerNetworkRequestMatchCallback(
1250                 any(IBinder.class), any(INetworkRequestMatchCallback.class),
1251                 callbackIdentifier.capture());
1252 
1253         mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
1254         verify(mWifiService).unregisterNetworkRequestMatchCallback(
1255                 eq((int) callbackIdentifier.getValue()));
1256     }
1257 
1258     /**
1259      * Verify the call to NetworkRequestUserSelectionCallback goes to
1260      * WifiServiceImpl.
1261      */
1262     @Test
networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()1263     public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
1264             throws Exception {
1265         when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
1266         ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
1267                 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
1268         mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
1269         verify(mWifiService).registerNetworkRequestMatchCallback(
1270                 any(IBinder.class), callbackCaptor.capture(), anyInt());
1271 
1272         INetworkRequestUserSelectionCallback iUserSelectionCallback =
1273                 mock(INetworkRequestUserSelectionCallback.class);
1274         ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
1275                 ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
1276         callbackCaptor.getValue().onUserSelectionCallbackRegistration(
1277                 iUserSelectionCallback);
1278         assertEquals(1, mLooper.dispatchAll());
1279         verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
1280                 userSelectionCallbackCaptor.capture());
1281 
1282         WifiConfiguration selected = new WifiConfiguration();
1283         userSelectionCallbackCaptor.getValue().select(selected);
1284         verify(iUserSelectionCallback).select(selected);
1285 
1286         userSelectionCallbackCaptor.getValue().reject();
1287         verify(iUserSelectionCallback).reject();
1288     }
1289 
1290     /**
1291      * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and
1292      * getWifiConfigsForPasspointProfiles of WifiService in order.
1293      */
1294     @Test
testGetAllMatchingWifiConfigs()1295     public void testGetAllMatchingWifiConfigs() throws Exception {
1296         Map<String, List<ScanResult>> fqdns = new HashMap<>();
1297         fqdns.put("www.test.com", new ArrayList<>());
1298         when(mWifiService.getAllMatchingFqdnsForScanResults(any(List.class))).thenReturn(fqdns);
1299         InOrder inOrder = inOrder(mWifiService);
1300 
1301         mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>());
1302 
1303         inOrder.verify(mWifiService).getAllMatchingFqdnsForScanResults(any(List.class));
1304         inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class));
1305     }
1306 
1307     /**
1308      * Check the call to getMatchingOsuProviders calls getMatchingOsuProviders of WifiService
1309      * with the provided a list of ScanResult.
1310      */
1311     @Test
testGetMatchingOsuProviders()1312     public void testGetMatchingOsuProviders() throws Exception {
1313         mWifiManager.getMatchingOsuProviders(new ArrayList<>());
1314 
1315         verify(mWifiService).getMatchingOsuProviders(any(List.class));
1316     }
1317 
1318     /**
1319      * Verify calls to {@link WifiManager#addNetworkSuggestions(List)} and
1320      * {@link WifiManager#removeNetworkSuggestions(List)}.
1321      */
1322     @Test
addRemoveNetworkSuggestions()1323     public void addRemoveNetworkSuggestions() throws Exception {
1324         when(mWifiService.addNetworkSuggestions(any(List.class), anyString()))
1325                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
1326         when(mWifiService.removeNetworkSuggestions(any(List.class), anyString()))
1327                 .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
1328 
1329         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
1330                 mWifiManager.addNetworkSuggestions(new ArrayList<>()));
1331         verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
1332 
1333         assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
1334                 mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
1335         verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
1336     }
1337 
1338     /**
1339      * Verify call to {@link WifiManager#getMaxNumberOfNetworkSuggestionsPerApp()}.
1340      */
1341     @Test
getMaxNumberOfNetworkSuggestionsPerApp()1342     public void getMaxNumberOfNetworkSuggestionsPerApp() {
1343         assertEquals(WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP,
1344                 mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp());
1345     }
1346 
1347     /**
1348      * Verify getting the factory MAC address.
1349      */
1350     @Test
testGetFactoryMacAddress()1351     public void testGetFactoryMacAddress() throws Exception {
1352         when(mWifiService.getFactoryMacAddresses()).thenReturn(TEST_MAC_ADDRESSES);
1353         assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses());
1354         verify(mWifiService).getFactoryMacAddresses();
1355     }
1356 
1357     /**
1358      * Verify the call to addOnWifiUsabilityStatsListener goes to WifiServiceImpl.
1359      */
1360     @Test
addOnWifiUsabilityStatsListeneroesToWifiServiceImpl()1361     public void addOnWifiUsabilityStatsListeneroesToWifiServiceImpl() throws Exception {
1362         mExecutor = new SynchronousExecutor();
1363         mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
1364         verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
1365                 any(IOnWifiUsabilityStatsListener.Stub.class), anyInt());
1366     }
1367 
1368     /**
1369      * Verify the call to removeOnWifiUsabilityStatsListener goes to WifiServiceImpl.
1370      */
1371     @Test
removeOnWifiUsabilityListenerGoesToWifiServiceImpl()1372     public void removeOnWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception {
1373         ArgumentCaptor<Integer> listenerIdentifier = ArgumentCaptor.forClass(Integer.class);
1374         mExecutor = new SynchronousExecutor();
1375         mWifiManager.addOnWifiUsabilityStatsListener(mExecutor, mOnWifiUsabilityStatsListener);
1376         verify(mWifiService).addOnWifiUsabilityStatsListener(any(IBinder.class),
1377                 any(IOnWifiUsabilityStatsListener.Stub.class), listenerIdentifier.capture());
1378 
1379         mWifiManager.removeOnWifiUsabilityStatsListener(mOnWifiUsabilityStatsListener);
1380         verify(mWifiService).removeOnWifiUsabilityStatsListener(
1381                 eq((int) listenerIdentifier.getValue()));
1382     }
1383 
1384     /**
1385      * Defined for testing purpose.
1386      */
1387     class SynchronousExecutor implements Executor {
execute(Runnable r)1388         public void execute(Runnable r) {
1389             r.run();
1390         }
1391     }
1392 
1393     /**
1394      * Test behavior of isEnhancedOpenSupported
1395      */
1396     @Test
testIsEnhancedOpenSupported()1397     public void testIsEnhancedOpenSupported() throws Exception {
1398         when(mWifiService.getSupportedFeatures())
1399                 .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE));
1400         assertTrue(mWifiManager.isEnhancedOpenSupported());
1401         when(mWifiService.getSupportedFeatures())
1402                 .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE));
1403         assertFalse(mWifiManager.isEnhancedOpenSupported());
1404     }
1405 
1406     /**
1407      * Test behavior of isWpa3SaeSupported
1408      */
1409     @Test
testIsWpa3SaeSupported()1410     public void testIsWpa3SaeSupported() throws Exception {
1411         when(mWifiService.getSupportedFeatures())
1412                 .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE));
1413         assertTrue(mWifiManager.isWpa3SaeSupported());
1414         when(mWifiService.getSupportedFeatures())
1415                 .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE));
1416         assertFalse(mWifiManager.isWpa3SaeSupported());
1417     }
1418 
1419     /**
1420      * Test behavior of isWpa3SuiteBSupported
1421      */
1422     @Test
testIsWpa3SuiteBSupported()1423     public void testIsWpa3SuiteBSupported() throws Exception {
1424         when(mWifiService.getSupportedFeatures())
1425                 .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
1426         assertTrue(mWifiManager.isWpa3SuiteBSupported());
1427         when(mWifiService.getSupportedFeatures())
1428                 .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
1429         assertFalse(mWifiManager.isWpa3SuiteBSupported());
1430     }
1431 
1432     /**
1433      * Test behavior of isEasyConnectSupported
1434      */
1435     @Test
testIsEasyConnectSupported()1436     public void testIsEasyConnectSupported() throws Exception {
1437         when(mWifiService.getSupportedFeatures())
1438                 .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP));
1439         assertTrue(mWifiManager.isEasyConnectSupported());
1440         when(mWifiService.getSupportedFeatures())
1441                 .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP));
1442         assertFalse(mWifiManager.isEasyConnectSupported());
1443     }
1444 
1445     /**
1446      * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
1447      */
1448     @Test
testAddNetwork()1449     public void testAddNetwork() throws Exception {
1450         WifiConfiguration configuration = new WifiConfiguration();
1451         when(mWifiService.addOrUpdateNetwork(any(), anyString()))
1452                 .thenReturn(TEST_NETWORK_ID);
1453 
1454         assertEquals(mWifiManager.addNetwork(configuration), TEST_NETWORK_ID);
1455         verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
1456 
1457         // send a null config
1458         assertEquals(mWifiManager.addNetwork(null), -1);
1459     }
1460 
1461     /**
1462      * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)}
1463      */
1464     @Test
testUpdateNetwork()1465     public void testUpdateNetwork() throws Exception {
1466         WifiConfiguration configuration = new WifiConfiguration();
1467         when(mWifiService.addOrUpdateNetwork(any(), anyString()))
1468                 .thenReturn(TEST_NETWORK_ID);
1469 
1470         configuration.networkId = TEST_NETWORK_ID;
1471         assertEquals(mWifiManager.updateNetwork(configuration), TEST_NETWORK_ID);
1472         verify(mWifiService).addOrUpdateNetwork(configuration, mContext.getOpPackageName());
1473 
1474         // config with invalid network ID
1475         configuration.networkId = -1;
1476         assertEquals(mWifiManager.updateNetwork(configuration), -1);
1477 
1478         // send a null config
1479         assertEquals(mWifiManager.updateNetwork(null), -1);
1480     }
1481 
1482     /**
1483      * Test behavior of {@link WifiManager#enableNetwork(int, boolean)}
1484      */
1485     @Test
testEnableNetwork()1486     public void testEnableNetwork() throws Exception {
1487         when(mWifiService.enableNetwork(anyInt(), anyBoolean(), anyString()))
1488                 .thenReturn(true);
1489         assertTrue(mWifiManager.enableNetwork(TEST_NETWORK_ID, true));
1490         verify(mWifiService).enableNetwork(TEST_NETWORK_ID, true, mContext.getOpPackageName());
1491     }
1492 
1493     /**
1494      * Test behavior of {@link WifiManager#disableNetwork(int)}
1495      */
1496     @Test
testDisableNetwork()1497     public void testDisableNetwork() throws Exception {
1498         when(mWifiService.disableNetwork(anyInt(), anyString()))
1499                 .thenReturn(true);
1500         assertTrue(mWifiManager.disableNetwork(TEST_NETWORK_ID));
1501         verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName());
1502     }
1503 
1504     /**
1505      * Test behavior of {@link WifiManager#disconnect()}
1506      */
1507     @Test
testDisconnect()1508     public void testDisconnect() throws Exception {
1509         when(mWifiService.disconnect(anyString())).thenReturn(true);
1510         assertTrue(mWifiManager.disconnect());
1511         verify(mWifiService).disconnect(mContext.getOpPackageName());
1512     }
1513 
1514     /**
1515      * Test behavior of {@link WifiManager#reconnect()}
1516      */
1517     @Test
testReconnect()1518     public void testReconnect() throws Exception {
1519         when(mWifiService.reconnect(anyString())).thenReturn(true);
1520         assertTrue(mWifiManager.reconnect());
1521         verify(mWifiService).reconnect(mContext.getOpPackageName());
1522     }
1523 
1524     /**
1525      * Test behavior of {@link WifiManager#reassociate()}
1526      */
1527     @Test
testReassociate()1528     public void testReassociate() throws Exception {
1529         when(mWifiService.reassociate(anyString())).thenReturn(true);
1530         assertTrue(mWifiManager.reassociate());
1531         verify(mWifiService).reassociate(mContext.getOpPackageName());
1532     }
1533 
1534     /**
1535      * Test behavior of {@link WifiManager#getSupportedFeatures()}
1536      */
1537     @Test
testGetSupportedFeatures()1538     public void testGetSupportedFeatures() throws Exception {
1539         long supportedFeatures =
1540                 WifiManager.WIFI_FEATURE_SCANNER
1541                         | WifiManager.WIFI_FEATURE_PASSPOINT
1542                         | WifiManager.WIFI_FEATURE_P2P;
1543         when(mWifiService.getSupportedFeatures())
1544                 .thenReturn(Long.valueOf(supportedFeatures));
1545 
1546         assertTrue(mWifiManager.isWifiScannerSupported());
1547         assertTrue(mWifiManager.isPasspointSupported());
1548         assertTrue(mWifiManager.isP2pSupported());
1549         assertFalse(mWifiManager.isPortableHotspotSupported());
1550         assertFalse(mWifiManager.is5GHzBandSupported());
1551         assertFalse(mWifiManager.isDeviceToDeviceRttSupported());
1552         assertFalse(mWifiManager.isDeviceToApRttSupported());
1553         assertFalse(mWifiManager.isPreferredNetworkOffloadSupported());
1554         assertFalse(mWifiManager.isAdditionalStaSupported());
1555         assertFalse(mWifiManager.isTdlsSupported());
1556         assertFalse(mWifiManager.isOffChannelTdlsSupported());
1557         assertFalse(mWifiManager.isEnhancedPowerReportingSupported());
1558     }
1559 
1560     /**
1561      * Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()}
1562      */
1563     @Test
testGetControllerActivityEnergyInfo()1564     public void testGetControllerActivityEnergyInfo() throws Exception {
1565         WifiActivityEnergyInfo activityEnergyInfo =
1566                 new WifiActivityEnergyInfo(5, 3, 3, new long[]{5L, 5L, 5L}, 5, 5, 5, 5);
1567         when(mWifiService.reportActivityInfo()).thenReturn(activityEnergyInfo);
1568 
1569         assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo());
1570     }
1571 
1572     /**
1573      * Test behavior of {@link WifiManager#getConnectionInfo()}
1574      */
1575     @Test
testGetConnectionInfo()1576     public void testGetConnectionInfo() throws Exception {
1577         WifiInfo wifiInfo = new WifiInfo();
1578         when(mWifiService.getConnectionInfo(anyString())).thenReturn(wifiInfo);
1579 
1580         assertEquals(wifiInfo, mWifiManager.getConnectionInfo());
1581     }
1582 
1583     /**
1584      * Test behavior of {@link WifiManager#isDualModeSupported()} ()}
1585      */
1586     @Test
testIsDualModeSupported()1587     public void testIsDualModeSupported() throws Exception {
1588         when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true);
1589         assertTrue(mWifiManager.isDualModeSupported());
1590         verify(mWifiService).needs5GHzToAnyApBandConversion();
1591     }
1592 
1593     /**
1594      * Test behavior of {@link WifiManager#isDualBandSupported()}
1595      */
1596     @Test
testIsDualBandSupported()1597     public void testIsDualBandSupported() throws Exception {
1598         when(mWifiService.isDualBandSupported()).thenReturn(true);
1599         assertTrue(mWifiManager.isDualBandSupported());
1600         verify(mWifiService).isDualBandSupported();
1601     }
1602 
1603     /**
1604      * Test behavior of {@link WifiManager#getDhcpInfo()}
1605      */
1606     @Test
testGetDhcpInfo()1607     public void testGetDhcpInfo() throws Exception {
1608         DhcpInfo dhcpInfo = new DhcpInfo();
1609 
1610         when(mWifiService.getDhcpInfo()).thenReturn(dhcpInfo);
1611         assertEquals(dhcpInfo, mWifiManager.getDhcpInfo());
1612         verify(mWifiService).getDhcpInfo();
1613     }
1614 
1615     /**
1616      * Test behavior of {@link WifiManager#setWifiEnabled(boolean)}
1617      */
1618     @Test
testSetWifiEnabled()1619     public void testSetWifiEnabled() throws Exception {
1620         when(mWifiService.setWifiEnabled(anyString(), anyBoolean())).thenReturn(true);
1621         assertTrue(mWifiManager.setWifiEnabled(true));
1622         verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), true);
1623         assertTrue(mWifiManager.setWifiEnabled(false));
1624         verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false);
1625     }
1626 }
1627