WifiStateMachineTest.java revision a598d61dcfdbd14c42c36241e3c148eb661867be
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertTrue;
22import static org.mockito.Mockito.*;
23
24import android.app.ActivityManager;
25import android.app.test.TestAlarmManager;
26import android.app.test.MockAnswerUtil.AnswerWithArguments;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.pm.PackageManager;
30import android.content.pm.UserInfo;
31import android.content.res.Resources;
32import android.net.ConnectivityManager;
33import android.net.DhcpResults;
34import android.net.LinkProperties;
35import android.net.dhcp.DhcpClient;
36import android.net.ip.IpManager;
37import android.net.wifi.IClientInterface;
38import android.net.wifi.IWificond;
39import android.net.wifi.ScanResult;
40import android.net.wifi.SupplicantState;
41import android.net.wifi.WifiConfiguration;
42import android.net.wifi.WifiManager;
43import android.net.wifi.WifiScanner;
44import android.net.wifi.WifiSsid;
45import android.net.wifi.p2p.IWifiP2pManager;
46import android.os.BatteryStats;
47import android.os.Binder;
48import android.os.Handler;
49import android.os.HandlerThread;
50import android.os.IBinder;
51import android.os.IInterface;
52import android.os.INetworkManagementService;
53import android.os.IPowerManager;
54import android.os.Looper;
55import android.os.Message;
56import android.os.Messenger;
57import android.os.PowerManager;
58import android.os.RemoteException;
59import android.os.UserHandle;
60import android.os.UserManager;
61import android.os.test.TestLooper;
62import android.provider.Settings;
63import android.security.KeyStore;
64import android.telephony.TelephonyManager;
65import android.test.suitebuilder.annotation.SmallTest;
66import android.util.Base64;
67import android.util.Log;
68
69import com.android.internal.R;
70import com.android.internal.app.IBatteryStats;
71import com.android.internal.util.AsyncChannel;
72import com.android.internal.util.IState;
73import com.android.internal.util.StateMachine;
74import com.android.server.wifi.hotspot2.NetworkDetail;
75import com.android.server.wifi.hotspot2.Utils;
76import com.android.server.wifi.p2p.WifiP2pServiceImpl;
77
78import org.junit.After;
79import org.junit.Before;
80import org.junit.Test;
81import org.mockito.ArgumentCaptor;
82import org.mockito.Mock;
83import org.mockito.MockitoAnnotations;
84
85import java.io.ByteArrayOutputStream;
86import java.io.PrintWriter;
87import java.lang.reflect.Field;
88import java.lang.reflect.InvocationTargetException;
89import java.lang.reflect.Method;
90import java.util.ArrayList;
91import java.util.Arrays;
92import java.util.concurrent.CountDownLatch;
93import java.util.HashMap;
94import java.util.HashSet;
95import java.util.List;
96import java.util.Map;
97import java.util.Set;
98
99/**
100 * Unit tests for {@link com.android.server.wifi.WifiStateMachine}.
101 */
102@SmallTest
103public class WifiStateMachineTest {
104    public static final String TAG = "WifiStateMachineTest";
105
106    private static final int MANAGED_PROFILE_UID = 1100000;
107    private static final int OTHER_USER_UID = 1200000;
108    private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE =
109            (ActivityManager.isLowRamDeviceStatic()
110                    ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY
111                    : WifiStateMachine.NUM_LOG_RECS_VERBOSE);
112    private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\"";
113
114    private long mBinderToken;
115
116    private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) {
117        return mock(class1, withSettings().extraInterfaces(interfaces));
118    }
119
120    private static <T, I> IBinder mockService(Class<T> class1, Class<I> iface) {
121        T tImpl = mockWithInterfaces(class1, iface);
122        IBinder binder = mock(IBinder.class);
123        when(((IInterface) tImpl).asBinder()).thenReturn(binder);
124        when(binder.queryLocalInterface(iface.getCanonicalName()))
125                .thenReturn((IInterface) tImpl);
126        return binder;
127    }
128
129    private void enableDebugLogs() {
130        mWsm.enableVerboseLogging(1);
131    }
132
133    private class TestIpManager extends IpManager {
134        TestIpManager(Context context, String ifname, IpManager.Callback callback) {
135            // Call dependency-injection superclass constructor.
136            super(context, ifname, callback, mock(INetworkManagementService.class));
137        }
138
139        @Override
140        public void startProvisioning(IpManager.ProvisioningConfiguration config) {}
141
142        @Override
143        public void stop() {}
144
145        @Override
146        public void confirmConfiguration() {}
147
148        void injectDhcpSuccess(DhcpResults dhcpResults) {
149            mCallback.onNewDhcpResults(dhcpResults);
150            mCallback.onProvisioningSuccess(new LinkProperties());
151        }
152
153        void injectDhcpFailure() {
154            mCallback.onNewDhcpResults(null);
155            mCallback.onProvisioningFailure(new LinkProperties());
156        }
157    }
158
159    private FrameworkFacade getFrameworkFacade() throws Exception {
160        FrameworkFacade facade = mock(FrameworkFacade.class);
161
162        when(facade.makeWifiScanner(any(Context.class), any(Looper.class)))
163                .thenReturn(mWifiScanner);
164        when(facade.getService(Context.NETWORKMANAGEMENT_SERVICE)).thenReturn(
165                mockWithInterfaces(IBinder.class, INetworkManagementService.class));
166
167        IBinder p2pBinder = mockService(WifiP2pServiceImpl.class, IWifiP2pManager.class);
168        when(facade.getService(Context.WIFI_P2P_SERVICE)).thenReturn(p2pBinder);
169
170        WifiP2pServiceImpl p2pm = (WifiP2pServiceImpl) p2pBinder.queryLocalInterface(
171                IWifiP2pManager.class.getCanonicalName());
172
173        final CountDownLatch untilDone = new CountDownLatch(1);
174        mP2pThread = new HandlerThread("WifiP2pMockThread") {
175            @Override
176            protected void onLooperPrepared() {
177                untilDone.countDown();
178            }
179        };
180
181        mP2pThread.start();
182        untilDone.await();
183
184        Handler handler = new Handler(mP2pThread.getLooper());
185        when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler));
186
187        IBinder batteryStatsBinder = mockService(BatteryStats.class, IBatteryStats.class);
188        when(facade.getService(BatteryStats.SERVICE_NAME)).thenReturn(batteryStatsBinder);
189
190        when(facade.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class)))
191                .then(new AnswerWithArguments() {
192                    public IpManager answer(
193                            Context context, String ifname, IpManager.Callback callback) {
194                        mTestIpManager = new TestIpManager(context, ifname, callback);
195                        return mTestIpManager;
196                    }
197                });
198
199        when(facade.checkUidPermission(eq(android.Manifest.permission.OVERRIDE_WIFI_CONFIG),
200                anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
201
202        when(facade.makeWifiConfigManager(any(Context.class), any(WifiNative.class),
203                any(FrameworkFacade.class), any(Clock.class),
204                any(UserManager.class), any(KeyStore.class))).then(new AnswerWithArguments() {
205            public WifiConfigManager answer(Context context, WifiNative wifiNative,
206                    FrameworkFacade frameworkFacade, Clock clock,
207                    UserManager userManager, KeyStore keyStore){
208                mWifiConfigManager = new WifiConfigManager(context, wifiNative, frameworkFacade,
209                        clock, userManager, keyStore);
210                return mWifiConfigManager;
211            }
212        });
213        return facade;
214    }
215
216    private Context getContext() throws Exception {
217        PackageManager pkgMgr = mock(PackageManager.class);
218        when(pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
219
220        Context context = mock(Context.class);
221        when(context.getPackageManager()).thenReturn(pkgMgr);
222        when(context.getContentResolver()).thenReturn(mock(ContentResolver.class));
223
224        MockResources resources = new com.android.server.wifi.MockResources();
225        when(context.getResources()).thenReturn(resources);
226
227        ContentResolver cr = mock(ContentResolver.class);
228        when(context.getContentResolver()).thenReturn(cr);
229
230        when(context.getSystemService(Context.POWER_SERVICE)).thenReturn(
231                new PowerManager(context, mock(IPowerManager.class), new Handler()));
232
233        mAlarmManager = new TestAlarmManager();
234        when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn(
235                mAlarmManager.getAlarmManager());
236
237        when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
238                mock(ConnectivityManager.class));
239
240        return context;
241    }
242
243    private Resources getMockResources() {
244        MockResources resources = new MockResources();
245        resources.setBoolean(R.bool.config_wifi_enable_wifi_firmware_debugging, false);
246        return resources;
247    }
248
249    private IState getCurrentState() throws
250            NoSuchMethodException, InvocationTargetException, IllegalAccessException {
251        Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
252        method.setAccessible(true);
253        return (IState) method.invoke(mWsm);
254    }
255
256    private static HandlerThread getWsmHandlerThread(WifiStateMachine wsm) throws
257            NoSuchFieldException, InvocationTargetException, IllegalAccessException {
258        Field field = StateMachine.class.getDeclaredField("mSmThread");
259        field.setAccessible(true);
260        return (HandlerThread) field.get(wsm);
261    }
262
263    private static void stopLooper(final Looper looper) throws Exception {
264        new Handler(looper).post(new Runnable() {
265            @Override
266            public void run() {
267                looper.quitSafely();
268            }
269        });
270    }
271
272    private void dumpState() {
273        ByteArrayOutputStream stream = new ByteArrayOutputStream();
274        PrintWriter writer = new PrintWriter(stream);
275        mWsm.dump(null, writer, null);
276        writer.flush();
277        Log.d(TAG, "WifiStateMachine state -" + stream.toString());
278    }
279
280    private static ScanDetail getGoogleGuestScanDetail(int rssi) {
281        ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1];
282        ie[0] = ScanResults.generateSsidIe(sSSID);
283        NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq);
284        ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq,
285                Long.MAX_VALUE, /* needed so that scan results aren't rejected because
286                                   there older than scan start */
287                ie, new ArrayList<String>());
288        return detail;
289    }
290
291    private ArrayList<ScanDetail> getMockScanResults() {
292        ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825);
293        ArrayList<ScanDetail> list = sr.getScanDetailArrayList();
294
295        int rssi = -65;
296        list.add(getGoogleGuestScanDetail(rssi));
297        return list;
298    }
299
300    static final String   sSSID = "\"GoogleGuest\"";
301    static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID);
302    static final String   sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", "");
303    static final String   sBSSID = "01:02:03:04:05:06";
304    static final int      sFreq = 2437;
305
306    WifiStateMachine mWsm;
307    HandlerThread mWsmThread;
308    HandlerThread mP2pThread;
309    HandlerThread mSyncThread;
310    AsyncChannel  mWsmAsyncChannel;
311    TestAlarmManager mAlarmManager;
312    MockWifiMonitor mWifiMonitor;
313    TestIpManager mTestIpManager;
314    TestLooper mLooper;
315    WifiConfigManager mWifiConfigManager;
316
317    @Mock WifiNative mWifiNative;
318    @Mock WifiScanner mWifiScanner;
319    @Mock SupplicantStateTracker mSupplicantStateTracker;
320    @Mock WifiMetrics mWifiMetrics;
321    @Mock UserManager mUserManager;
322    @Mock WifiApConfigStore mApConfigStore;
323    @Mock BackupManagerProxy mBackupManagerProxy;
324    @Mock WifiCountryCode mCountryCode;
325    @Mock WifiInjector mWifiInjector;
326    @Mock WifiLastResortWatchdog mWifiLastResortWatchdog;
327    @Mock PropertyService mPropertyService;
328    @Mock BuildProperties mBuildProperties;
329    @Mock IWificond mWificond;
330    @Mock IClientInterface mClientInterface;
331    @Mock IBinder mClientInterfaceBinder;
332
333    public WifiStateMachineTest() throws Exception {
334    }
335
336    @Before
337    public void setUp() throws Exception {
338        Log.d(TAG, "Setting up ...");
339
340        // Ensure looper exists
341        mLooper = new TestLooper();
342
343        MockitoAnnotations.initMocks(this);
344
345        /** uncomment this to enable logs from WifiStateMachines */
346        // enableDebugLogs();
347
348        TestUtil.installWlanWifiNative(mWifiNative);
349        mWifiMonitor = new MockWifiMonitor();
350        when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
351        when(mWifiInjector.getClock()).thenReturn(mock(Clock.class));
352        when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog);
353        when(mWifiInjector.getPropertyService()).thenReturn(mPropertyService);
354        when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties);
355        when(mWifiInjector.getKeyStore()).thenReturn(mock(KeyStore.class));
356        when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class));
357        when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn(
358                mock(BaseWifiDiagnostics.class));
359        when(mWifiInjector.makeWificond()).thenReturn(mWificond);
360
361        FrameworkFacade factory = getFrameworkFacade();
362        Context context = getContext();
363
364        Resources resources = getMockResources();
365        when(context.getResources()).thenReturn(resources);
366
367        when(factory.getIntegerSetting(context,
368                Settings.Global.WIFI_FREQUENCY_BAND,
369                WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn(
370                WifiManager.WIFI_FREQUENCY_BAND_AUTO);
371
372        when(factory.makeApConfigStore(eq(context), eq(mBackupManagerProxy)))
373                .thenReturn(mApConfigStore);
374
375        when(factory.makeSupplicantStateTracker(
376                any(Context.class), any(WifiConfigManager.class),
377                any(Handler.class))).thenReturn(mSupplicantStateTracker);
378
379        when(mUserManager.getProfileParent(11))
380                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "owner", 0));
381        when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(Arrays.asList(
382                new UserInfo(UserHandle.USER_SYSTEM, "owner", 0),
383                new UserInfo(11, "managed profile", 0)));
384
385        when(mWificond.createClientInterface()).thenReturn(mClientInterface);
386        when(mClientInterface.asBinder()).thenReturn(mClientInterfaceBinder);
387
388        mWsm = new WifiStateMachine(context, factory, mLooper.getLooper(),
389            mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode);
390        mWsmThread = getWsmHandlerThread(mWsm);
391
392        final AsyncChannel channel = new AsyncChannel();
393        Handler handler = new Handler(mLooper.getLooper()) {
394            @Override
395            public void handleMessage(Message msg) {
396                switch (msg.what) {
397                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
398                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
399                            mWsmAsyncChannel = channel;
400                        } else {
401                            Log.d(TAG, "Failed to connect Command channel " + this);
402                        }
403                        break;
404                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
405                        Log.d(TAG, "Command channel disconnected" + this);
406                        break;
407                }
408            }
409        };
410
411        channel.connect(context, handler, mWsm.getMessenger());
412        mLooper.dispatchAll();
413        /* Now channel is supposed to be connected */
414
415        mBinderToken = Binder.clearCallingIdentity();
416    }
417
418    @After
419    public void cleanUp() throws Exception {
420        Binder.restoreCallingIdentity(mBinderToken);
421
422        if (mSyncThread != null) stopLooper(mSyncThread.getLooper());
423        if (mWsmThread != null) stopLooper(mWsmThread.getLooper());
424        if (mP2pThread != null) stopLooper(mP2pThread.getLooper());
425
426        mWsmThread = null;
427        mP2pThread = null;
428        mSyncThread = null;
429        mWsmAsyncChannel = null;
430        mWsm = null;
431    }
432
433    @Test
434    public void createNew() throws Exception {
435        assertEquals("InitialState", getCurrentState().getName());
436
437        mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED);
438        mLooper.dispatchAll();
439        assertEquals("InitialState", getCurrentState().getName());
440    }
441
442    @Test
443    public void loadComponents() throws Exception {
444        when(mWifiNative.startHal()).thenReturn(true);
445        when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(true);
446        mWsm.setSupplicantRunning(true);
447        mLooper.dispatchAll();
448
449        assertEquals("SupplicantStartingState", getCurrentState().getName());
450
451        when(mWifiNative.setBand(anyInt())).thenReturn(true);
452        when(mWifiNative.setDeviceName(anyString())).thenReturn(true);
453        when(mWifiNative.setManufacturer(anyString())).thenReturn(true);
454        when(mWifiNative.setModelName(anyString())).thenReturn(true);
455        when(mWifiNative.setModelNumber(anyString())).thenReturn(true);
456        when(mWifiNative.setSerialNumber(anyString())).thenReturn(true);
457        when(mWifiNative.setConfigMethods(anyString())).thenReturn(true);
458        when(mWifiNative.setDeviceType(anyString())).thenReturn(true);
459        when(mWifiNative.setSerialNumber(anyString())).thenReturn(true);
460        when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true);
461
462        mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT);
463        mLooper.dispatchAll();
464
465        assertEquals("DisconnectedState", getCurrentState().getName());
466    }
467
468    @Test
469    public void shouldRequireHalToLeaveInitialState() throws Exception {
470        when(mWifiNative.startHal()).thenReturn(false);
471        mWsm.setSupplicantRunning(true);
472        mLooper.dispatchAll();
473        assertEquals("InitialState", getCurrentState().getName());
474    }
475
476    @Test
477    public void shouldRequireSupplicantStartupToLeaveInitialState() throws Exception {
478        when(mWifiNative.startSupplicant(true)).thenReturn(false);
479        mWsm.setSupplicantRunning(true);
480        mLooper.dispatchAll();
481        assertEquals("InitialState", getCurrentState().getName());
482    }
483
484    @Test
485    public void shouldRequireWificondToLeaveInitialState() throws Exception {
486        // We start out with valid default values, break them going backwards so that
487        // we test all the bailout cases.
488
489        // ClientInterface dies after creation.
490        doThrow(new RemoteException()).when(mClientInterfaceBinder).linkToDeath(any(), anyInt());
491        mWsm.setSupplicantRunning(true);
492        mLooper.dispatchAll();
493        assertEquals("InitialState", getCurrentState().getName());
494
495        // Failed to even create the client interface.
496        when(mWificond.createClientInterface()).thenReturn(null);
497        mWsm.setSupplicantRunning(true);
498        mLooper.dispatchAll();
499        assertEquals("InitialState", getCurrentState().getName());
500
501        // Failed to get wificond proxy.
502        when(mWifiInjector.makeWificond()).thenReturn(null);
503        mWsm.setSupplicantRunning(true);
504        mLooper.dispatchAll();
505        assertEquals("InitialState", getCurrentState().getName());
506    }
507
508    @Test
509    public void loadComponentsFailure() throws Exception {
510        when(mWifiNative.startHal()).thenReturn(false);
511        when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(false);
512
513        mWsm.setSupplicantRunning(true);
514        mLooper.dispatchAll();
515        assertEquals("InitialState", getCurrentState().getName());
516
517        when(mWifiNative.startHal()).thenReturn(true);
518        mWsm.setSupplicantRunning(true);
519        mLooper.dispatchAll();
520        assertEquals("InitialState", getCurrentState().getName());
521    }
522
523    private void addNetworkAndVerifySuccess() throws Exception {
524        addNetworkAndVerifySuccess(false);
525    }
526
527    private void addNetworkAndVerifySuccess(boolean isHidden) throws Exception {
528        loadComponents();
529
530        final HashMap<String, String> nameToValue = new HashMap<>();
531
532        when(mWifiNative.addNetwork()).thenReturn(0);
533        when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString()))
534                .then(new AnswerWithArguments() {
535                    public boolean answer(int netId, String name, String value) {
536                        if (netId != 0) {
537                            Log.d(TAG, "Can't set var " + name + " for " + netId);
538                            return false;
539                        }
540
541                        Log.d(TAG, "Setting var " + name + " to " + value + " for " + netId);
542                        nameToValue.put(name, value);
543                        return true;
544                    }
545                });
546
547        when(mWifiNative.setNetworkExtra(anyInt(), anyString(), (Map<String, String>) anyObject()))
548                .then(new AnswerWithArguments() {
549                    public boolean answer(int netId, String name, Map<String, String> values) {
550                        if (netId != 0) {
551                            Log.d(TAG, "Can't set extra " + name + " for " + netId);
552                            return false;
553                        }
554
555                        Log.d(TAG, "Setting extra for " + netId);
556                        return true;
557                    }
558                });
559
560        when(mWifiNative.getNetworkVariable(anyInt(), anyString()))
561                .then(new AnswerWithArguments() {
562                    public String answer(int netId, String name) throws Throwable {
563                        if (netId != 0) {
564                            Log.d(TAG, "Can't find var " + name + " for " + netId);
565                            return null;
566                        }
567                        String value = nameToValue.get(name);
568                        if (value != null) {
569                            Log.d(TAG, "Returning var " + name + " to " + value + " for " + netId);
570                        } else {
571                            Log.d(TAG, "Can't find var " + name + " for " + netId);
572                        }
573                        return value;
574                    }
575                });
576
577        WifiConfiguration config = new WifiConfiguration();
578        config.SSID = sSSID;
579        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
580        config.hiddenSSID = isHidden;
581        mLooper.startAutoDispatch();
582        mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config);
583        mLooper.stopAutoDispatch();
584
585        verify(mWifiNative).addNetwork();
586        verify(mWifiNative).setNetworkVariable(0, "ssid", sHexSSID);
587        if (isHidden) {
588            verify(mWifiNative).setNetworkVariable(0, "scan_ssid", Integer.toString(1));
589        }
590
591        mLooper.startAutoDispatch();
592        List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel);
593        mLooper.stopAutoDispatch();
594        assertEquals(1, configs.size());
595
596        WifiConfiguration config2 = configs.get(0);
597        assertEquals("\"GoogleGuest\"", config2.SSID);
598        assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE));
599    }
600
601    private void addNetworkAndVerifyFailure() throws Exception {
602        loadComponents();
603
604        final WifiConfiguration config = new WifiConfiguration();
605        config.SSID = sSSID;
606        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
607
608        mLooper.startAutoDispatch();
609        mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config);
610        mLooper.stopAutoDispatch();
611
612        verify(mWifiNative, never()).addNetwork();
613        verify(mWifiNative, never()).setNetworkVariable(anyInt(), anyString(), anyString());
614
615        mLooper.startAutoDispatch();
616        assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty());
617        mLooper.stopAutoDispatch();
618    }
619
620    /**
621     * Verifies that the current foreground user is allowed to add a network.
622     */
623    @Test
624    public void addNetworkAsCurrentUser() throws Exception {
625        addNetworkAndVerifySuccess();
626    }
627
628    /**
629     * Verifies that a managed profile of the current foreground user is allowed to add a network.
630     */
631    @Test
632    public void addNetworkAsCurrentUsersManagedProfile() throws Exception {
633        BinderUtil.setUid(MANAGED_PROFILE_UID);
634        addNetworkAndVerifySuccess();
635    }
636
637    /**
638     * Verifies that a background user is not allowed to add a network.
639     */
640    @Test
641    public void addNetworkAsOtherUser() throws Exception {
642        BinderUtil.setUid(OTHER_USER_UID);
643        addNetworkAndVerifyFailure();
644    }
645
646    private void removeNetworkAndVerifySuccess() throws Exception {
647        when(mWifiNative.removeNetwork(0)).thenReturn(true);
648        mLooper.startAutoDispatch();
649        assertTrue(mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0));
650        mLooper.stopAutoDispatch();
651
652        mLooper.startAutoDispatch();
653        assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty());
654        mLooper.stopAutoDispatch();
655    }
656
657    private void removeNetworkAndVerifyFailure() throws Exception {
658        mLooper.startAutoDispatch();
659        assertFalse(mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0));
660        mLooper.stopAutoDispatch();
661
662        mLooper.startAutoDispatch();
663        assertEquals(1, mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).size());
664        mLooper.stopAutoDispatch();
665        verify(mWifiNative, never()).removeNetwork(anyInt());
666    }
667
668    /**
669     * Verifies that the current foreground user is allowed to remove a network.
670     */
671    @Test
672    public void removeNetworkAsCurrentUser() throws Exception {
673        addNetworkAndVerifySuccess();
674        removeNetworkAndVerifySuccess();
675    }
676
677    /**
678     * Verifies that a managed profile of the current foreground user is allowed to remove a
679     * network.
680     */
681    @Test
682    public void removeNetworkAsCurrentUsersManagedProfile() throws Exception {
683        addNetworkAndVerifySuccess();
684        BinderUtil.setUid(MANAGED_PROFILE_UID);
685        removeNetworkAndVerifySuccess();
686    }
687
688    /**
689     * Verifies that a background user is not allowed to remove a network.
690     */
691    @Test
692    public void removeNetworkAsOtherUser() throws Exception {
693        addNetworkAndVerifySuccess();
694        BinderUtil.setUid(OTHER_USER_UID);
695        removeNetworkAndVerifyFailure();
696    }
697
698    private void enableNetworkAndVerifySuccess() throws Exception {
699        when(mWifiNative.selectNetwork(0)).thenReturn(true);
700
701        mLooper.startAutoDispatch();
702        assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true));
703        mLooper.stopAutoDispatch();
704
705        verify(mWifiNative).selectNetwork(0);
706    }
707
708    private void enableNetworkAndVerifyFailure() throws Exception {
709        mLooper.startAutoDispatch();
710        assertFalse(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true));
711        mLooper.stopAutoDispatch();
712
713        verify(mWifiNative, never()).selectNetwork(anyInt());
714    }
715
716    /**
717     * Verifies that the current foreground user is allowed to enable a network.
718     */
719    @Test
720    public void enableNetworkAsCurrentUser() throws Exception {
721        addNetworkAndVerifySuccess();
722        enableNetworkAndVerifySuccess();
723    }
724
725    /**
726     * Verifies that a managed profile of the current foreground user is allowed to enable a
727     * network.
728     */
729    @Test
730    public void enableNetworkAsCurrentUsersManagedProfile() throws Exception {
731        addNetworkAndVerifySuccess();
732        BinderUtil.setUid(MANAGED_PROFILE_UID);
733        enableNetworkAndVerifySuccess();
734    }
735
736    /**
737     * Verifies that a background user is not allowed to enable a network.
738     */
739    @Test
740    public void enableNetworkAsOtherUser() throws Exception {
741        addNetworkAndVerifySuccess();
742        BinderUtil.setUid(OTHER_USER_UID);
743        enableNetworkAndVerifyFailure();
744    }
745
746    private void forgetNetworkAndVerifySuccess() throws Exception {
747        when(mWifiNative.removeNetwork(0)).thenReturn(true);
748        mLooper.startAutoDispatch();
749        final Message result =
750                mWsmAsyncChannel.sendMessageSynchronously(WifiManager.FORGET_NETWORK, 0);
751        mLooper.stopAutoDispatch();
752        assertEquals(WifiManager.FORGET_NETWORK_SUCCEEDED, result.what);
753        result.recycle();
754        mLooper.startAutoDispatch();
755        assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty());
756        mLooper.stopAutoDispatch();
757    }
758
759    private void forgetNetworkAndVerifyFailure() throws Exception {
760        mLooper.startAutoDispatch();
761        final Message result =
762                mWsmAsyncChannel.sendMessageSynchronously(WifiManager.FORGET_NETWORK, 0);
763        mLooper.stopAutoDispatch();
764        assertEquals(WifiManager.FORGET_NETWORK_FAILED, result.what);
765        result.recycle();
766        mLooper.startAutoDispatch();
767        assertEquals(1, mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).size());
768        mLooper.stopAutoDispatch();
769        verify(mWifiNative, never()).removeNetwork(anyInt());
770    }
771
772    /**
773     * Helper method to retrieve WifiConfiguration by SSID.
774     *
775     * Returns the associated WifiConfiguration if it is found, null otherwise.
776     */
777    private WifiConfiguration getWifiConfigurationForNetwork(String ssid) {
778        mLooper.startAutoDispatch();
779        List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel);
780        mLooper.stopAutoDispatch();
781
782        for (WifiConfiguration checkConfig : configs) {
783            if (checkConfig.SSID.equals(ssid)) {
784                return checkConfig;
785            }
786        }
787        return null;
788    }
789
790    /**
791     * Verifies that the current foreground user is allowed to forget a network.
792     */
793    @Test
794    public void forgetNetworkAsCurrentUser() throws Exception {
795        addNetworkAndVerifySuccess();
796        forgetNetworkAndVerifySuccess();
797    }
798
799    /**
800     * Verifies that a managed profile of the current foreground user is allowed to forget a
801     * network.
802     */
803    @Test
804    public void forgetNetworkAsCurrentUsersManagedProfile() throws Exception {
805        addNetworkAndVerifySuccess();
806        BinderUtil.setUid(MANAGED_PROFILE_UID);
807        forgetNetworkAndVerifySuccess();
808    }
809
810    /**
811     * Verifies that a background user is not allowed to forget a network.
812     */
813    @Test
814    public void forgetNetworkAsOtherUser() throws Exception {
815        addNetworkAndVerifySuccess();
816        BinderUtil.setUid(OTHER_USER_UID);
817        forgetNetworkAndVerifyFailure();
818    }
819
820    private void verifyScan(int band, int reportEvents, Set<Integer> configuredNetworkIds) {
821        ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor =
822                ArgumentCaptor.forClass(WifiScanner.ScanSettings.class);
823        ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor =
824                ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
825        verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture(),
826                eq(null));
827        WifiScanner.ScanSettings actualSettings = scanSettingsCaptor.getValue();
828        assertEquals("band", band, actualSettings.band);
829        assertEquals("reportEvents", reportEvents, actualSettings.reportEvents);
830
831        if (configuredNetworkIds == null) {
832            configuredNetworkIds = new HashSet<>();
833        }
834        Set<Integer> actualConfiguredNetworkIds = new HashSet<>();
835        if (actualSettings.hiddenNetworkIds != null) {
836            for (int i = 0; i < actualSettings.hiddenNetworkIds.length; ++i) {
837                actualConfiguredNetworkIds.add(actualSettings.hiddenNetworkIds[i]);
838            }
839        }
840        assertEquals("configured networks", configuredNetworkIds, actualConfiguredNetworkIds);
841
842        when(mWifiNative.getScanResults()).thenReturn(getMockScanResults());
843        mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT);
844
845        mLooper.dispatchAll();
846
847        List<ScanResult> reportedResults = mWsm.syncGetScanResultsList();
848        assertEquals(8, reportedResults.size());
849    }
850
851    @Test
852    public void scan() throws Exception {
853        addNetworkAndVerifySuccess();
854
855        mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
856        mWsm.startScan(-1, 0, null, null);
857        mLooper.dispatchAll();
858
859        verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
860                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
861                | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, null);
862    }
863
864    @Test
865    public void scanWithHiddenNetwork() throws Exception {
866        addNetworkAndVerifySuccess(true);
867
868        mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
869        mWsm.startScan(-1, 0, null, null);
870        mLooper.dispatchAll();
871
872        verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
873                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
874                | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
875                mWifiConfigManager.getHiddenConfiguredNetworkIds());
876    }
877
878    @Test
879    public void connect() throws Exception {
880        addNetworkAndVerifySuccess();
881
882        mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
883        mLooper.dispatchAll();
884
885        mLooper.startAutoDispatch();
886        mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true);
887        mLooper.stopAutoDispatch();
888
889        verify(mWifiNative).selectNetwork(0);
890
891        mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
892        mLooper.dispatchAll();
893
894        mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
895                new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
896        mLooper.dispatchAll();
897
898        assertEquals("ObtainingIpState", getCurrentState().getName());
899
900        DhcpResults dhcpResults = new DhcpResults();
901        dhcpResults.setGateway("1.2.3.4");
902        dhcpResults.setIpAddress("192.168.1.100", 0);
903        dhcpResults.addDns("8.8.8.8");
904        dhcpResults.setLeaseDuration(3600);
905
906        mTestIpManager.injectDhcpSuccess(dhcpResults);
907        mLooper.dispatchAll();
908
909        assertEquals("ConnectedState", getCurrentState().getName());
910    }
911
912    @Test
913    public void testDhcpFailure() throws Exception {
914        addNetworkAndVerifySuccess();
915
916        mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
917        mLooper.dispatchAll();
918
919        mLooper.startAutoDispatch();
920        mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true);
921        mLooper.stopAutoDispatch();
922
923        verify(mWifiNative).selectNetwork(0);
924
925        mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
926        mLooper.dispatchAll();
927
928        mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
929                new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
930        mLooper.dispatchAll();
931
932        assertEquals("ObtainingIpState", getCurrentState().getName());
933
934        mTestIpManager.injectDhcpFailure();
935        mLooper.dispatchAll();
936
937        assertEquals("DisconnectingState", getCurrentState().getName());
938    }
939
940    @Test
941    public void testBadNetworkEvent() throws Exception {
942        addNetworkAndVerifySuccess();
943
944        mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
945        mLooper.dispatchAll();
946
947        mLooper.startAutoDispatch();
948        mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true);
949        mLooper.stopAutoDispatch();
950
951        verify(mWifiNative).selectNetwork(0);
952
953        mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID);
954        mLooper.dispatchAll();
955
956        mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
957                new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
958        mLooper.dispatchAll();
959
960        assertEquals("DisconnectedState", getCurrentState().getName());
961    }
962
963
964    @Test
965    public void smToString() throws Exception {
966        assertEquals("CMD_CHANNEL_HALF_CONNECTED", mWsm.smToString(
967                AsyncChannel.CMD_CHANNEL_HALF_CONNECTED));
968        assertEquals("CMD_PRE_DHCP_ACTION", mWsm.smToString(
969                DhcpClient.CMD_PRE_DHCP_ACTION));
970        assertEquals("CMD_IP_REACHABILITY_LOST", mWsm.smToString(
971                WifiStateMachine.CMD_IP_REACHABILITY_LOST));
972    }
973
974    @Test
975    public void disconnect() throws Exception {
976        connect();
977
978        mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06");
979        mLooper.dispatchAll();
980        mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
981                new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED));
982        mLooper.dispatchAll();
983
984        assertEquals("DisconnectedState", getCurrentState().getName());
985    }
986
987    /**
988     * WifiConfigurations default to HasEverConnected to false,  creating and adding a config should
989     * not update this value to true.
990     *
991     * Test: Successfully add a network. Check the config and verify
992     * WifiConfiguration.getHasEverConnected() is false.
993     */
994    @Test
995    public void addNetworkDoesNotSetHasEverConnectedTrue() throws Exception {
996        addNetworkAndVerifySuccess();
997
998        WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
999        assertFalse(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
1000    }
1001
1002    /**
1003     * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected
1004     * to true.
1005     *
1006     * Test: Successfully create and connect to a network. Check the config and verify
1007     * WifiConfiguration.getHasEverConnected() is true.
1008     */
1009    @Test
1010    public void setHasEverConnectedTrueOnConnect() throws Exception {
1011        connect();
1012
1013        WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
1014        assertTrue(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
1015    }
1016
1017    /**
1018     * Fail network connection attempt and verify HasEverConnected remains false.
1019     *
1020     * Test: Successfully create a network but fail when connecting. Check the config and verify
1021     * WifiConfiguration.getHasEverConnected() is false.
1022     */
1023    @Test
1024    public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception {
1025        testDhcpFailure();
1026
1027        WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
1028        assertFalse(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
1029    }
1030
1031    @Test
1032    public void handleUserSwitch() throws Exception {
1033        assertEquals(UserHandle.USER_SYSTEM, mWifiConfigManager.getCurrentUserId());
1034
1035        mWsm.handleUserSwitch(10);
1036        mLooper.dispatchAll();
1037
1038        assertEquals(10, mWifiConfigManager.getCurrentUserId());
1039    }
1040
1041    @Test
1042    public void iconQueryTest() throws Exception {
1043        /* enable wi-fi */
1044        addNetworkAndVerifySuccess();
1045
1046        long bssid = 0x1234567800FFL;
1047        String filename = "iconFileName.png";
1048        String command = "REQ_HS20_ICON " + Utils.macToString(bssid) + " " + filename;
1049
1050        when(mWifiNative.doCustomSupplicantCommand(command)).thenReturn("OK");
1051
1052        mLooper.startAutoDispatch();
1053        boolean result = mWsm.syncQueryPasspointIcon(mWsmAsyncChannel, bssid, filename);
1054        mLooper.stopAutoDispatch();
1055
1056        verify(mWifiNative).doCustomSupplicantCommand(command);
1057        assertEquals(true, result);
1058    }
1059
1060    private String createSimChallengeRequest(byte[] challengeValue) {
1061        // Produce a base64 encoded length byte + data.
1062        byte[] challengeLengthAndValue = new byte[challengeValue.length + 1];
1063        challengeLengthAndValue[0] = (byte) challengeValue.length;
1064        for (int i = 0; i < challengeValue.length; ++i) {
1065            challengeLengthAndValue[i + 1] = challengeValue[i];
1066        }
1067        return Base64.encodeToString(challengeLengthAndValue, android.util.Base64.NO_WRAP);
1068    }
1069
1070    private String createSimAuthResponse(byte[] sresValue, byte[] kcValue) {
1071        // Produce a base64 encoded sres length byte + sres + kc length byte + kc.
1072        int overallLength = sresValue.length + kcValue.length + 2;
1073        byte[] result = new byte[sresValue.length + kcValue.length + 2];
1074        int idx = 0;
1075        result[idx++] = (byte) sresValue.length;
1076        for (int i = 0; i < sresValue.length; ++i) {
1077            result[idx++] = sresValue[i];
1078        }
1079        result[idx++] = (byte) kcValue.length;
1080        for (int i = 0; i < kcValue.length; ++i) {
1081            result[idx++] = kcValue[i];
1082        }
1083        return Base64.encodeToString(result, Base64.NO_WRAP);
1084    }
1085
1086    /** Verifies function getGsmSimAuthResponse method. */
1087    @Test
1088    public void getGsmSimAuthResponseTest() throws Exception {
1089        TelephonyManager tm = mock(TelephonyManager.class);
1090        final String[] invalidRequests = { null, "", "XXXX" };
1091        assertEquals("", mWsm.getGsmSimAuthResponse(invalidRequests, tm));
1092
1093        final String[] failedRequests = { "5E5F" };
1094        when(tm.getIccAuthentication(anyInt(), anyInt(),
1095                eq(createSimChallengeRequest(new byte[] { 0x5e, 0x5f })))).thenReturn(null);
1096        assertEquals(null, mWsm.getGsmSimAuthResponse(failedRequests, tm));
1097
1098        when(tm.getIccAuthentication(2, tm.AUTHTYPE_EAP_SIM,
1099                createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
1100                .thenReturn(null);
1101        when(tm.getIccAuthentication(1, tm.AUTHTYPE_EAP_SIM,
1102                createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
1103                .thenReturn(createSimAuthResponse(new byte[] { 0x1D, 0x2C },
1104                       new byte[] { 0x3B, 0x4A }));
1105        when(tm.getIccAuthentication(1, tm.AUTHTYPE_EAP_SIM,
1106                createSimChallengeRequest(new byte[] { 0x01, 0x23 })))
1107                .thenReturn(createSimAuthResponse(new byte[] { 0x33, 0x22 },
1108                        new byte[] { 0x11, 0x00 }));
1109        assertEquals(":3b4a:1d2c:1100:3322", mWsm.getGsmSimAuthResponse(
1110                new String[] { "1A2B", "0123" }, tm));
1111    }
1112
1113    /**
1114     * Verifies that, by default, we allow only the "normal" number of log records.
1115     */
1116    @Test
1117    public void normalLogRecSizeIsUsedByDefault() {
1118        for (int i = 0; i < WifiStateMachine.NUM_LOG_RECS_NORMAL * 2; i++) {
1119            mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED);
1120        }
1121        mLooper.dispatchAll();
1122        assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecSize());
1123    }
1124
1125    /**
1126     * Verifies that, in verbose mode, we allow a larger number of log records.
1127     */
1128    @Test
1129    public void enablingVerboseLoggingIncreasesLogRecSize() {
1130        assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > WifiStateMachine.NUM_LOG_RECS_NORMAL);
1131        mWsm.enableVerboseLogging(1);
1132        for (int i = 0; i < LOG_REC_LIMIT_IN_VERBOSE_MODE * 2; i++) {
1133            mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED);
1134        }
1135        mLooper.dispatchAll();
1136        assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mWsm.getLogRecSize());
1137    }
1138
1139    /**
1140     * Verifies that moving from verbose mode to normal mode resets the buffer, and limits new
1141     * records to a small number of entries.
1142     */
1143    @Test
1144    public void disablingVerboseLoggingClearsRecordsAndDecreasesLogRecSize() {
1145        mWsm.enableVerboseLogging(1);
1146        for (int i = 0; i < LOG_REC_LIMIT_IN_VERBOSE_MODE; i++) {
1147            mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED);
1148        }
1149        mLooper.dispatchAll();
1150        assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mWsm.getLogRecSize());
1151
1152        mWsm.enableVerboseLogging(0);
1153        assertEquals(0, mWsm.getLogRecSize());
1154        for (int i = 0; i < LOG_REC_LIMIT_IN_VERBOSE_MODE; i++) {
1155            mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED);
1156        }
1157        mLooper.dispatchAll();
1158        assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecSize());
1159    }
1160
1161    /** Verifies that enabling verbose logging sets the hal log property in eng builds. */
1162    @Test
1163    public void enablingVerboseLoggingSetsHalLogPropertyInEngBuilds() {
1164        reset(mPropertyService);  // Ignore calls made in setUp()
1165        when(mBuildProperties.isEngBuild()).thenReturn(true);
1166        when(mBuildProperties.isUserdebugBuild()).thenReturn(false);
1167        when(mBuildProperties.isUserBuild()).thenReturn(false);
1168        mWsm.enableVerboseLogging(1);
1169        verify(mPropertyService).set("log.tag.WifiHAL", "V");
1170    }
1171
1172    /** Verifies that enabling verbose logging sets the hal log property in userdebug builds. */
1173    @Test
1174    public void enablingVerboseLoggingSetsHalLogPropertyInUserdebugBuilds() {
1175        reset(mPropertyService);  // Ignore calls made in setUp()
1176        when(mBuildProperties.isUserdebugBuild()).thenReturn(true);
1177        when(mBuildProperties.isEngBuild()).thenReturn(false);
1178        when(mBuildProperties.isUserBuild()).thenReturn(false);
1179        mWsm.enableVerboseLogging(1);
1180        verify(mPropertyService).set("log.tag.WifiHAL", "V");
1181    }
1182
1183    /** Verifies that enabling verbose logging does NOT set the hal log property in user builds. */
1184    @Test
1185    public void enablingVerboseLoggingDoeNotSetHalLogPropertyInUserBuilds() {
1186        reset(mPropertyService);  // Ignore calls made in setUp()
1187        when(mBuildProperties.isUserBuild()).thenReturn(true);
1188        when(mBuildProperties.isEngBuild()).thenReturn(false);
1189        when(mBuildProperties.isUserdebugBuild()).thenReturn(false);
1190        mWsm.enableVerboseLogging(1);
1191        verify(mPropertyService, never()).set(anyString(), anyString());
1192    }
1193}
1194