HalDeviceManagerTest.java revision d887e5c6bf4abf2f098ea6f087e717e29c551548
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
17package com.android.server.wifi;
18
19import static org.hamcrest.core.IsEqual.equalTo;
20import static org.mockito.Matchers.any;
21import static org.mockito.Matchers.anyInt;
22import static org.mockito.Matchers.anyLong;
23import static org.mockito.Matchers.anyString;
24import static org.mockito.Matchers.eq;
25import static org.mockito.Mockito.doAnswer;
26import static org.mockito.Mockito.inOrder;
27import static org.mockito.Mockito.mock;
28import static org.mockito.Mockito.times;
29import static org.mockito.Mockito.verify;
30import static org.mockito.Mockito.verifyNoMoreInteractions;
31import static org.mockito.Mockito.when;
32
33import android.app.test.MockAnswerUtil;
34import android.hardware.wifi.V1_0.IWifi;
35import android.hardware.wifi.V1_0.IWifiApIface;
36import android.hardware.wifi.V1_0.IWifiChip;
37import android.hardware.wifi.V1_0.IWifiChipEventCallback;
38import android.hardware.wifi.V1_0.IWifiEventCallback;
39import android.hardware.wifi.V1_0.IWifiIface;
40import android.hardware.wifi.V1_0.IWifiNanIface;
41import android.hardware.wifi.V1_0.IWifiP2pIface;
42import android.hardware.wifi.V1_0.IWifiStaIface;
43import android.hardware.wifi.V1_0.IfaceType;
44import android.hardware.wifi.V1_0.WifiStatus;
45import android.hardware.wifi.V1_0.WifiStatusCode;
46import android.hidl.manager.V1_0.IServiceManager;
47import android.hidl.manager.V1_0.IServiceNotification;
48import android.os.IHwBinder;
49import android.os.test.TestLooper;
50import android.util.Log;
51
52import org.hamcrest.core.IsNull;
53import org.junit.After;
54import org.junit.Before;
55import org.junit.Rule;
56import org.junit.Test;
57import org.junit.rules.ErrorCollector;
58import org.mockito.ArgumentCaptor;
59import org.mockito.InOrder;
60import org.mockito.Mock;
61import org.mockito.MockitoAnnotations;
62
63import java.io.PrintWriter;
64import java.io.StringWriter;
65import java.util.ArrayList;
66import java.util.HashMap;
67import java.util.Map;
68
69/**
70 * Unit test harness for HalDeviceManagerTest.
71 */
72public class HalDeviceManagerTest {
73    private HalDeviceManager mDut;
74    @Mock IServiceManager mServiceManagerMock;
75    @Mock IWifi mWifiMock;
76    @Mock HalDeviceManager.ManagerStatusCallback mManagerStatusCallbackMock;
77    private TestLooper mTestLooper;
78    private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
79            ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
80    private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
81            ArgumentCaptor.forClass(IServiceNotification.Stub.class);
82    private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
83            IWifiEventCallback.class);
84    private InOrder mInOrder;
85    @Rule public ErrorCollector collector = new ErrorCollector();
86    private WifiStatus mStatusOk;
87    private WifiStatus mStatusFail;
88
89    private class HalDeviceManagerSpy extends HalDeviceManager {
90        @Override
91        protected IWifi getWifiServiceMockable() {
92            return mWifiMock;
93        }
94
95        @Override
96        protected IServiceManager getServiceManagerMockable() {
97            return mServiceManagerMock;
98        }
99    }
100
101    @Before
102    public void before() throws Exception {
103        MockitoAnnotations.initMocks(this);
104
105        mTestLooper = new TestLooper();
106
107        // initialize dummy status objects
108        mStatusOk = getStatus(WifiStatusCode.SUCCESS);
109        mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
110
111        when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
112                anyLong())).thenReturn(true);
113        when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
114                any(IServiceNotification.Stub.class))).thenReturn(true);
115        when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
116                true);
117        when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
118        when(mWifiMock.start()).thenReturn(mStatusOk);
119        when(mWifiMock.stop()).thenReturn(mStatusOk);
120
121        mDut = new HalDeviceManagerSpy();
122    }
123
124    /**
125     * Print out the dump of the device manager after each test. Not used in test validation
126     * (internal state) - but can help in debugging failed tests.
127     */
128    @After
129    public void after() throws Exception {
130        dumpDut("after: ");
131    }
132
133    /**
134     * Test basic startup flow:
135     * - IServiceManager registrations
136     * - IWifi registrations
137     * - IWifi startup delayed
138     * - Start Wi-Fi -> onStart
139     * - Stop Wi-Fi -> onStop
140     */
141    @Test
142    public void testStartStopFlow() throws Exception {
143        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusCallbackMock);
144        executeAndValidateInitializationSequence();
145        executeAndValidateStartupSequence();
146
147        // act: stop Wi-Fi
148        mDut.stop();
149        mTestLooper.dispatchAll();
150
151        // verify: onStop called
152        mInOrder.verify(mWifiMock).stop();
153        mInOrder.verify(mManagerStatusCallbackMock).onStop();
154
155        verifyNoMoreInteractions(mManagerStatusCallbackMock);
156    }
157
158    /**
159     * Validate that multiple callback registrations are called and that duplicate ones are
160     * only called once.
161     */
162    @Test
163    public void testMultipleCallbackRegistrations() throws Exception {
164        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusCallbackMock);
165        executeAndValidateInitializationSequence();
166
167        // register another 2 callbacks - one of them twice
168        HalDeviceManager.ManagerStatusCallback callback1 = mock(
169                HalDeviceManager.ManagerStatusCallback.class);
170        HalDeviceManager.ManagerStatusCallback callback2 = mock(
171                HalDeviceManager.ManagerStatusCallback.class);
172        mDut.registerStatusCallback(callback2, mTestLooper.getLooper());
173        mDut.registerStatusCallback(callback1, mTestLooper.getLooper());
174        mDut.registerStatusCallback(callback2, mTestLooper.getLooper());
175
176        // startup
177        executeAndValidateStartupSequence();
178
179        // verify
180        verify(callback1).onStart();
181        verify(callback2).onStart();
182
183        verifyNoMoreInteractions(mManagerStatusCallbackMock, callback1, callback2);
184    }
185
186    /**
187     * Validate IWifi death listener and registration flow.
188     */
189    @Test
190    public void testWifiDeathAndRegistration() throws Exception {
191        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusCallbackMock);
192        executeAndValidateInitializationSequence();
193        executeAndValidateStartupSequence();
194
195        // act: IWifi service death
196        mDeathRecipientCaptor.getValue().serviceDied(0);
197        mTestLooper.dispatchAll();
198
199        // verify: getting onStop
200        mInOrder.verify(mManagerStatusCallbackMock).onStop();
201
202        // act: service startup
203        mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
204
205        // verify: initialization of IWifi
206        mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
207        mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
208
209        // act: start
210        mDut.start();
211        mWifiEventCallbackCaptor.getValue().onStart();
212        mTestLooper.dispatchAll();
213
214        // verify: service and callback calls
215        mInOrder.verify(mWifiMock).start();
216        mInOrder.verify(mManagerStatusCallbackMock).onStart();
217
218        verifyNoMoreInteractions(mManagerStatusCallbackMock);
219    }
220
221    /**
222     * Validate IWifi onFailure causes notification
223     */
224    @Test
225    public void testWifiFail() throws Exception {
226        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusCallbackMock);
227        executeAndValidateInitializationSequence();
228        executeAndValidateStartupSequence();
229
230        // act: IWifi failure
231        mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
232        mTestLooper.dispatchAll();
233
234        // verify: getting onStop
235        mInOrder.verify(mManagerStatusCallbackMock).onStop();
236
237        // act: start again
238        mDut.start();
239        mWifiEventCallbackCaptor.getValue().onStart();
240        mTestLooper.dispatchAll();
241
242        // verify: service and callback calls
243        mInOrder.verify(mWifiMock).start();
244        mInOrder.verify(mManagerStatusCallbackMock).onStart();
245
246        verifyNoMoreInteractions(mManagerStatusCallbackMock);
247    }
248
249    /**
250     * Validate creation of STA interface from blank start-up. The remove interface.
251     */
252    @Test
253    public void testCreateStaInterfaceNoInitMode() throws Exception {
254        final String name = "sta0";
255
256        BaselineChip chipMock = new BaselineChip();
257        chipMock.initialize();
258        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
259                mManagerStatusCallbackMock);
260        executeAndValidateInitializationSequence();
261        executeAndValidateStartupSequence();
262
263        HalDeviceManager.InterfaceDestroyedListener idl = mock(
264                HalDeviceManager.InterfaceDestroyedListener.class);
265        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
266                HalDeviceManager.InterfaceAvailableForRequestListener.class);
267
268        IWifiStaIface iface = (IWifiStaIface) validateInterfaceSequence(chipMock, false, -1000,
269                IfaceType.STA, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl);
270        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
271
272        // act: remove interface
273        mDut.removeIface(iface);
274        mTestLooper.dispatchAll();
275
276        // verify: callback triggered
277        mInOrder.verify(chipMock.chip).removeStaIface(name);
278        verify(idl).onDestroyed();
279
280        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
281    }
282
283    /**
284     * Validate creation of AP interface from blank start-up. The remove interface.
285     */
286    @Test
287    public void testCreateApInterfaceNoInitMode() throws Exception {
288        final String name = "ap0";
289
290        BaselineChip chipMock = new BaselineChip();
291        chipMock.initialize();
292        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
293                mManagerStatusCallbackMock);
294        executeAndValidateInitializationSequence();
295        executeAndValidateStartupSequence();
296
297        HalDeviceManager.InterfaceDestroyedListener idl = mock(
298                HalDeviceManager.InterfaceDestroyedListener.class);
299        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
300                HalDeviceManager.InterfaceAvailableForRequestListener.class);
301
302        IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, false, -1000,
303                IfaceType.AP, name, BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl);
304        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
305
306        // act: remove interface
307        mDut.removeIface(iface);
308        mTestLooper.dispatchAll();
309
310        // verify: callback triggered
311        mInOrder.verify(chipMock.chip).removeApIface(name);
312        verify(idl).onDestroyed();
313
314        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
315    }
316
317    /**
318     * Validate creation of P2P interface from blank start-up. The remove interface.
319     */
320    @Test
321    public void testCreateP2pInterfaceNoInitMode() throws Exception {
322        final String name = "p2p0";
323
324        BaselineChip chipMock = new BaselineChip();
325        chipMock.initialize();
326        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
327                mManagerStatusCallbackMock);
328        executeAndValidateInitializationSequence();
329        executeAndValidateStartupSequence();
330
331        HalDeviceManager.InterfaceDestroyedListener idl = mock(
332                HalDeviceManager.InterfaceDestroyedListener.class);
333        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
334                HalDeviceManager.InterfaceAvailableForRequestListener.class);
335
336        IWifiP2pIface iface = (IWifiP2pIface) validateInterfaceSequence(chipMock, false, -1000,
337                IfaceType.P2P, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl);
338        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
339
340        // act: remove interface
341        mDut.removeIface(iface);
342        mTestLooper.dispatchAll();
343
344        // verify: callback triggered
345        mInOrder.verify(chipMock.chip).removeP2pIface(name);
346        verify(idl).onDestroyed();
347
348        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
349    }
350
351    /**
352     * Validate creation of NAN interface from blank start-up. The remove interface.
353     */
354    @Test
355    public void testCreateNanInterfaceNoInitMode() throws Exception {
356        final String name = "nan0";
357
358        BaselineChip chipMock = new BaselineChip();
359        chipMock.initialize();
360        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
361                mManagerStatusCallbackMock);
362        executeAndValidateInitializationSequence();
363        executeAndValidateStartupSequence();
364
365        HalDeviceManager.InterfaceDestroyedListener idl = mock(
366                HalDeviceManager.InterfaceDestroyedListener.class);
367        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
368                HalDeviceManager.InterfaceAvailableForRequestListener.class);
369
370        IWifiNanIface iface = (IWifiNanIface) validateInterfaceSequence(chipMock, false, -1000,
371                IfaceType.NAN, name, BaselineChip.STA_CHIP_MODE_ID, null, idl, iafrl);
372        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
373
374        // act: remove interface
375        mDut.removeIface(iface);
376        mTestLooper.dispatchAll();
377
378        // verify: callback triggered
379        mInOrder.verify(chipMock.chip).removeNanIface(name);
380        verify(idl).onDestroyed();
381
382        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
383    }
384
385    /**
386     * Validate creation of AP interface when in STA mode - but with no interface created. Expect
387     * a change in chip mode.
388     */
389    @Test
390    public void testCreateApWithStaModeUp() throws Exception {
391        final String name = "ap0";
392
393        BaselineChip chipMock = new BaselineChip();
394        chipMock.initialize();
395        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
396                mManagerStatusCallbackMock);
397        executeAndValidateInitializationSequence();
398        executeAndValidateStartupSequence();
399
400        HalDeviceManager.InterfaceDestroyedListener idl = mock(
401                HalDeviceManager.InterfaceDestroyedListener.class);
402        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
403                HalDeviceManager.InterfaceAvailableForRequestListener.class);
404
405        IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, true,
406                BaselineChip.STA_CHIP_MODE_ID, IfaceType.AP, name,
407                BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl);
408        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
409
410        // act: stop Wi-Fi
411        mDut.stop();
412        mTestLooper.dispatchAll();
413
414        // verify: callback triggered
415        verify(idl).onDestroyed();
416        verify(mManagerStatusCallbackMock).onStop();
417
418        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
419    }
420
421    /**
422     * Validate creation of AP interface when in AP mode - but with no interface created. Expect
423     * no change in chip mode.
424     */
425    @Test
426    public void testCreateApWithApModeUp() throws Exception {
427        final String name = "ap0";
428
429        BaselineChip chipMock = new BaselineChip();
430        chipMock.initialize();
431        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
432                mManagerStatusCallbackMock);
433        executeAndValidateInitializationSequence();
434        executeAndValidateStartupSequence();
435
436        HalDeviceManager.InterfaceDestroyedListener idl = mock(
437                HalDeviceManager.InterfaceDestroyedListener.class);
438        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
439                HalDeviceManager.InterfaceAvailableForRequestListener.class);
440
441        IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock, true,
442                BaselineChip.AP_CHIP_MODE_ID, IfaceType.AP, name,
443                BaselineChip.AP_CHIP_MODE_ID, null, idl, iafrl);
444        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
445
446        // act: stop Wi-Fi
447        mDut.stop();
448        mTestLooper.dispatchAll();
449
450        // verify: callback triggered
451        verify(idl).onDestroyed();
452        verify(mManagerStatusCallbackMock).onStop();
453
454        verifyNoMoreInteractions(mManagerStatusCallbackMock, idl, iafrl);
455    }
456
457    /**
458     * Validate AP up/down creation of AP interface when a STA already created. Expect:
459     * - STA created
460     * - P2P created
461     * - When AP requested:
462     *   - STA & P2P torn down
463     *   - AP created
464     * - P2P creation refused
465     * - Request STA: will tear down AP
466     * - When AP destroyed:
467     *   - Get p2p available listener callback
468     *   - Can create P2P when requested
469     * - Create P2P
470     * - Request NAN: will get refused
471     * - Tear down P2P:
472     *    - should get nan available listener callback
473     *    - Can create NAN when requested
474     */
475    @Test
476    public void testCreateSameAndDiffPriorities() throws Exception {
477        BaselineChip chipMock = new BaselineChip();
478        chipMock.initialize();
479        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
480                mManagerStatusCallbackMock);
481        executeAndValidateInitializationSequence();
482        executeAndValidateStartupSequence();
483
484        HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
485                HalDeviceManager.InterfaceDestroyedListener.class);
486        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
487                HalDeviceManager.InterfaceAvailableForRequestListener.class);
488
489        HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock(
490                HalDeviceManager.InterfaceDestroyedListener.class);
491
492        HalDeviceManager.InterfaceDestroyedListener apDestroyedListener = mock(
493                HalDeviceManager.InterfaceDestroyedListener.class);
494        HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
495                HalDeviceManager.InterfaceAvailableForRequestListener.class);
496
497        HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
498                HalDeviceManager.InterfaceDestroyedListener.class);
499        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
500                HalDeviceManager.InterfaceAvailableForRequestListener.class);
501
502        HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener2 = mock(
503                HalDeviceManager.InterfaceDestroyedListener.class);
504
505        HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
506                HalDeviceManager.InterfaceDestroyedListener.class);
507        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
508                HalDeviceManager.InterfaceAvailableForRequestListener.class);
509
510        // Request STA
511        IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA,
512                "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener,
513                staAvailListener);
514        collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
515
516        // register additional InterfaceDestroyedListeners - including a duplicate (verify that
517        // only called once!)
518        mDut.registerDestroyedListener(staIface, staDestroyedListener2, mTestLooper.getLooper());
519        mDut.registerDestroyedListener(staIface, staDestroyedListener, mTestLooper.getLooper());
520
521        // Request P2P
522        IWifiIface p2pIface = validateInterfaceSequence(chipMock, true,
523                BaselineChip.STA_CHIP_MODE_ID, IfaceType.P2P, "p2p0", BaselineChip.STA_CHIP_MODE_ID,
524                null, p2pDestroyedListener, p2pAvailListener);
525        collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
526
527        // Request AP
528        IWifiIface apIface = validateInterfaceSequence(chipMock, true,
529                BaselineChip.STA_CHIP_MODE_ID, IfaceType.AP, "ap0", BaselineChip.AP_CHIP_MODE_ID,
530                new IWifiIface[]{staIface, p2pIface}, apDestroyedListener, apAvailListener,
531                staDestroyedListener, staDestroyedListener2, p2pDestroyedListener);
532        collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue());
533
534        // Request P2P: expect failure
535        p2pIface = mDut.createP2pIface(p2pDestroyedListener, p2pAvailListener,
536                mTestLooper.getLooper());
537        collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue());
538
539        // Request STA: expect success
540        staIface = validateInterfaceSequence(chipMock, true, BaselineChip.AP_CHIP_MODE_ID,
541                IfaceType.STA, "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener,
542                staAvailListener, apDestroyedListener);
543        collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
544
545        mTestLooper.dispatchAll();
546        verify(apDestroyedListener).onDestroyed();
547        verify(p2pAvailListener).onAvailableForRequest();
548
549        // Request P2P: expect success now
550        p2pIface = validateInterfaceSequence(chipMock, true, BaselineChip.STA_CHIP_MODE_ID,
551                IfaceType.STA, "p2p0", BaselineChip.STA_CHIP_MODE_ID, null, p2pDestroyedListener2,
552                p2pAvailListener);
553
554        // Request NAN: should fail
555        IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener,
556                mTestLooper.getLooper());
557        collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
558
559        // Tear down P2P
560        mDut.removeIface(p2pIface);
561        mTestLooper.dispatchAll();
562
563        verify(chipMock.chip).removeP2pIface("p2p0");
564        verify(p2pDestroyedListener2).onDestroyed();
565        verify(nanAvailListener).onAvailableForRequest();
566
567        // Should now be able to request and get NAN
568        nanIface = validateInterfaceSequence(chipMock, true, BaselineChip.STA_CHIP_MODE_ID,
569                IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID, null, nanDestroyedListener,
570                nanAvailListener);
571        collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
572
573        verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener,
574                staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener,
575                nanDestroyedListener, nanAvailListener, p2pDestroyedListener2);
576    }
577
578    /**
579     * Validate P2P and NAN interactions. Expect:
580     * - STA created
581     * - NAN created
582     * - When P2P requested:
583     *   - NAN torn down
584     *   - P2P created
585     * - NAN creation refused
586     * - When P2P destroyed:
587     *   - get nan available listener
588     *   - Can create NAN when requested
589     */
590    @Test
591    public void testP2pAndNanInteractions() throws Exception {
592        BaselineChip chipMock = new BaselineChip();
593        chipMock.initialize();
594        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
595                mManagerStatusCallbackMock);
596        executeAndValidateInitializationSequence();
597        executeAndValidateStartupSequence();
598
599        HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
600                HalDeviceManager.InterfaceDestroyedListener.class);
601        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
602                HalDeviceManager.InterfaceAvailableForRequestListener.class);
603
604        HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
605                HalDeviceManager.InterfaceDestroyedListener.class);
606        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
607                HalDeviceManager.InterfaceAvailableForRequestListener.class);
608
609        HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
610                HalDeviceManager.InterfaceDestroyedListener.class);
611        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = null;
612
613        // Request STA
614        IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA,
615                "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener,
616                staAvailListener);
617
618        // Request NAN
619        IWifiIface nanIface = validateInterfaceSequence(chipMock, true,
620                BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID,
621                null, nanDestroyedListener, nanAvailListener);
622
623        // Request P2P
624        IWifiIface p2pIface = validateInterfaceSequence(chipMock, true,
625                BaselineChip.STA_CHIP_MODE_ID, IfaceType.P2P, "p2p0", BaselineChip.STA_CHIP_MODE_ID,
626                new IWifiIface[]{nanIface}, p2pDestroyedListener, p2pAvailListener,
627                nanDestroyedListener);
628
629        // Request NAN: expect failure
630        nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener,
631                mTestLooper.getLooper());
632        collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
633
634        // Destroy P2P interface
635        boolean status = mDut.removeIface(p2pIface);
636        mInOrder.verify(chipMock.chip).removeP2pIface("p2p0");
637        collector.checkThat("P2P removal success", status, equalTo(true));
638
639        mTestLooper.dispatchAll();
640        verify(p2pDestroyedListener).onDestroyed();
641        verify(nanAvailListener).onAvailableForRequest();
642
643        // Request NAN: expect success now
644        nanIface = validateInterfaceSequence(chipMock, true,
645                BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID,
646                null, nanDestroyedListener, nanAvailListener);
647
648        verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener,
649                nanDestroyedListener, nanAvailListener, p2pDestroyedListener);
650    }
651
652    /**
653     * Validates that when (for some reason) the cache is out-of-sync with the actual chip status
654     * then Wi-Fi is shut-down.
655     */
656    @Test
657    public void testCacheMismatchError() throws Exception {
658        BaselineChip chipMock = new BaselineChip();
659        chipMock.initialize();
660        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
661                mManagerStatusCallbackMock);
662        executeAndValidateInitializationSequence();
663        executeAndValidateStartupSequence();
664
665        HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
666                HalDeviceManager.InterfaceDestroyedListener.class);
667        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
668                HalDeviceManager.InterfaceAvailableForRequestListener.class);
669
670        HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
671                HalDeviceManager.InterfaceDestroyedListener.class);
672        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
673                HalDeviceManager.InterfaceAvailableForRequestListener.class);
674
675        // Request STA
676        IWifiIface staIface = validateInterfaceSequence(chipMock, false, -1000, IfaceType.STA,
677                "sta0", BaselineChip.STA_CHIP_MODE_ID, null, staDestroyedListener,
678                staAvailListener);
679
680        // Request NAN
681        IWifiIface nanIface = validateInterfaceSequence(chipMock, true,
682                BaselineChip.STA_CHIP_MODE_ID, IfaceType.NAN, "nan0", BaselineChip.STA_CHIP_MODE_ID,
683                null, nanDestroyedListener, nanAvailListener);
684
685        // fiddle with the "chip" by removing the STA
686        chipMock.interfaceNames.get(IfaceType.STA).remove("sta0");
687
688        // now try to request another NAN
689        nanIface = mDut.createNanIface(nanDestroyedListener, nanAvailListener,
690                mTestLooper.getLooper());
691        collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
692
693        // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
694        // registered (even if they seem out-of-sync to chip)
695        mTestLooper.dispatchAll();
696        verify(mWifiMock).stop();
697        verify(mManagerStatusCallbackMock).onStop();
698        verify(staDestroyedListener).onDestroyed();
699        verify(nanDestroyedListener).onDestroyed();
700
701        verifyNoMoreInteractions(mManagerStatusCallbackMock, staDestroyedListener, staAvailListener,
702                nanDestroyedListener, nanAvailListener);
703    }
704
705    // utilities
706    private void dumpDut(String prefix) {
707        StringWriter sw = new StringWriter();
708        mDut.dump(null, new PrintWriter(sw), null);
709        Log.e("HalDeviceManager", prefix + sw.toString());
710    }
711
712    private void executeAndValidateInitializationSequence() throws Exception {
713        InOrder inOrder = inOrder(mServiceManagerMock, mWifiMock);
714
715        // act:
716        mDut.initialize();
717
718        // verify: service manager initialization sequence
719        mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
720                anyLong());
721        inOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
722                eq(""), mServiceNotificationCaptor.capture());
723
724        // act: get the service started (which happens even when service was already up)
725        mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
726
727        // verify: wifi initialization sequence
728        inOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
729        inOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
730    }
731
732    private void executeAndValidateStartupSequence() throws Exception {
733        // act: register listener & start Wi-Fi
734        mDut.registerStatusCallback(mManagerStatusCallbackMock, mTestLooper.getLooper());
735        mDut.start();
736
737        // verify
738        mInOrder.verify(mWifiMock).start();
739
740        // act: trigger onStart callback of IWifiEventCallback
741        mWifiEventCallbackCaptor.getValue().onStart();
742        mTestLooper.dispatchAll();
743
744        // verify: onStart called on registered listener
745        mInOrder.verify(mManagerStatusCallbackMock).onStart();
746    }
747
748    private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
749            boolean chipModeValid, int chipModeId,
750            int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList,
751            HalDeviceManager.InterfaceDestroyedListener destroyedListener,
752            HalDeviceManager.InterfaceAvailableForRequestListener availableListener,
753            HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners)
754            throws Exception {
755        // configure chip mode response
756        chipMock.chipModeValid = chipModeValid;
757        chipMock.chipModeId = chipModeId;
758
759        IWifiIface iface = null;
760
761        // configure: interface to be created
762        // act: request the interface
763        switch (ifaceTypeToCreate) {
764            case IfaceType.STA:
765                iface = mock(IWifiStaIface.class);
766                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
767                        any(IWifiIface.getNameCallback.class));
768                doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
769                        any(IWifiIface.getTypeCallback.class));
770                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
771                        chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
772
773                mDut.createStaIface(destroyedListener, availableListener, mTestLooper.getLooper());
774                break;
775            case IfaceType.AP:
776                iface = mock(IWifiApIface.class);
777                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
778                        any(IWifiIface.getNameCallback.class));
779                doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
780                        any(IWifiIface.getTypeCallback.class));
781                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
782                        chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
783
784                mDut.createApIface(destroyedListener, availableListener, mTestLooper.getLooper());
785                break;
786            case IfaceType.P2P:
787                iface = mock(IWifiP2pIface.class);
788                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
789                        any(IWifiIface.getNameCallback.class));
790                doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
791                        any(IWifiIface.getTypeCallback.class));
792                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
793                        chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
794
795                mDut.createP2pIface(destroyedListener, availableListener, mTestLooper.getLooper());
796                break;
797            case IfaceType.NAN:
798                iface = mock(IWifiNanIface.class);
799                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
800                        any(IWifiIface.getNameCallback.class));
801                doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
802                        any(IWifiIface.getTypeCallback.class));
803                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
804                        chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
805
806                mDut.createNanIface(destroyedListener, availableListener, mTestLooper.getLooper());
807                break;
808        }
809
810        // validate: optional tear down of interfaces
811        if (tearDownList != null) {
812            for (IWifiIface tearDownIface: tearDownList) {
813                switch (getType(tearDownIface)) {
814                    case IfaceType.STA:
815                        mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
816                        break;
817                    case IfaceType.AP:
818                        mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
819                        break;
820                    case IfaceType.P2P:
821                        mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
822                        break;
823                    case IfaceType.NAN:
824                        mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
825                        break;
826                }
827            }
828        }
829
830        // validate: optional switch to the requested mode
831        if (!chipModeValid || chipModeId != finalChipMode) {
832            mInOrder.verify(chipMock.chip).configureChip(finalChipMode);
833        } else {
834            mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt());
835        }
836
837        // validate: create STA
838        switch (ifaceTypeToCreate) {
839            case IfaceType.STA:
840                mInOrder.verify(chipMock.chip).createStaIface(
841                        any(IWifiChip.createStaIfaceCallback.class));
842                break;
843            case IfaceType.AP:
844                mInOrder.verify(chipMock.chip).createApIface(
845                        any(IWifiChip.createApIfaceCallback.class));
846                break;
847            case IfaceType.P2P:
848                mInOrder.verify(chipMock.chip).createP2pIface(
849                        any(IWifiChip.createP2pIfaceCallback.class));
850                break;
851            case IfaceType.NAN:
852                mInOrder.verify(chipMock.chip).createNanIface(
853                        any(IWifiChip.createNanIfaceCallback.class));
854                break;
855        }
856
857        // verify: callbacks on deleted interfaces
858        mTestLooper.dispatchAll();
859        for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) {
860            verify(destroyedInterfacesDestroyedListeners[i]).onDestroyed();
861        }
862
863        return iface;
864    }
865
866    private int getType(IWifiIface iface) throws Exception {
867        Mutable<Integer> typeResp = new Mutable<>();
868        iface.getType((WifiStatus status, int type) -> {
869            typeResp.value = type;
870        });
871        return typeResp.value;
872    }
873
874    private String getName(IWifiIface iface) throws Exception {
875        Mutable<String> nameResp = new Mutable<>();
876        iface.getName((WifiStatus status, String name) -> {
877            nameResp.value = name;
878        });
879        return nameResp.value;
880    }
881
882    private WifiStatus getStatus(int code) {
883        WifiStatus status = new WifiStatus();
884        status.code = code;
885        return status;
886    }
887
888    private static class Mutable<E> {
889        public E value;
890
891        Mutable() {
892            value = null;
893        }
894
895        Mutable(E value) {
896            this.value = value;
897        }
898    }
899
900    // Answer objects
901    private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
902        private WifiStatus mStatus;
903        private ArrayList<Integer> mChipIds;
904
905        GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
906            mStatus = status;
907            mChipIds = chipIds;
908        }
909
910        public void answer(IWifi.getChipIdsCallback cb) {
911            cb.onValues(mStatus, mChipIds);
912        }
913    }
914
915    private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
916        private WifiStatus mStatus;
917        private IWifiChip mChip;
918
919        GetChipAnswer(WifiStatus status, IWifiChip chip) {
920            mStatus = status;
921            mChip = chip;
922        }
923
924        public void answer(int chipId, IWifi.getChipCallback cb) {
925            cb.onValues(mStatus, mChip);
926        }
927    }
928
929    private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments {
930        private ChipMockBase mChipMockBase;
931
932        GetAvailableModesAnswer(ChipMockBase chipMockBase) {
933            mChipMockBase = chipMockBase;
934        }
935
936        public void answer(IWifiChip.getAvailableModesCallback cb) {
937            cb.onValues(mStatusOk, mChipMockBase.availableModes);
938        }
939    }
940
941    private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments {
942        private ChipMockBase mChipMockBase;
943
944        GetModeAnswer(ChipMockBase chipMockBase) {
945            mChipMockBase = chipMockBase;
946        }
947
948        public void answer(IWifiChip.getModeCallback cb) {
949            cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
950                    : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
951        }
952    }
953
954    private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments {
955        private ChipMockBase mChipMockBase;
956
957        ConfigureChipAnswer(ChipMockBase chipMockBase) {
958            mChipMockBase = chipMockBase;
959        }
960
961        public WifiStatus answer(int chipMode) {
962            mChipMockBase.chipModeId = chipMode;
963            return mStatusOk;
964        }
965    }
966
967    private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
968        private ChipMockBase mChipMockBase;
969
970        GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
971            mChipMockBase = chipMockBase;
972        }
973
974        public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
975            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
976        }
977
978        public void answer(IWifiChip.getApIfaceNamesCallback cb) {
979            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
980        }
981
982        public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
983            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
984        }
985
986        public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
987            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
988        }
989    }
990
991    private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
992        private ChipMockBase mChipMockBase;
993
994        GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
995            mChipMockBase = chipMockBase;
996        }
997
998        public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
999            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
1000            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
1001        }
1002
1003        public void answer(String name, IWifiChip.getApIfaceCallback cb) {
1004            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
1005            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
1006        }
1007
1008        public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
1009            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
1010            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
1011        }
1012
1013        public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
1014            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
1015            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
1016        }
1017    }
1018
1019    private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
1020        private ChipMockBase mChipMockBase;
1021        private WifiStatus mStatus;
1022        private IWifiIface mWifiIface;
1023
1024        CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
1025            mChipMockBase = chipMockBase;
1026            mStatus = status;
1027            mWifiIface = wifiIface;
1028        }
1029
1030        private void addInterfaceInfo(int type) {
1031            if (mStatus.code == WifiStatusCode.SUCCESS) {
1032                try {
1033                    mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
1034                    mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
1035                } catch (Exception e) {
1036                    // do nothing
1037                }
1038            }
1039        }
1040
1041        public void answer(IWifiChip.createStaIfaceCallback cb) {
1042            cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
1043            addInterfaceInfo(IfaceType.STA);
1044        }
1045
1046        public void answer(IWifiChip.createApIfaceCallback cb) {
1047            cb.onValues(mStatus, (IWifiApIface) mWifiIface);
1048            addInterfaceInfo(IfaceType.AP);
1049        }
1050
1051        public void answer(IWifiChip.createP2pIfaceCallback cb) {
1052            cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
1053            addInterfaceInfo(IfaceType.P2P);
1054        }
1055
1056        public void answer(IWifiChip.createNanIfaceCallback cb) {
1057            cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
1058            addInterfaceInfo(IfaceType.NAN);
1059        }
1060    }
1061
1062    private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
1063        private ChipMockBase mChipMockBase;
1064        private int mType;
1065
1066        RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
1067            mChipMockBase = chipMockBase;
1068            mType = type;
1069        }
1070
1071        private WifiStatus removeIface(int type, String ifname) {
1072            try {
1073                if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
1074                    return mStatusFail;
1075                }
1076                if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
1077                    return mStatusFail;
1078                }
1079            } catch (Exception e) {
1080                return mStatusFail;
1081            }
1082            return mStatusOk;
1083        }
1084
1085        public WifiStatus answer(String ifname) {
1086            return removeIface(mType, ifname);
1087        }
1088    }
1089
1090    private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments {
1091        private String mName;
1092
1093        GetNameAnswer(String name) {
1094            mName = name;
1095        }
1096
1097        public void answer(IWifiIface.getNameCallback cb) {
1098            cb.onValues(mStatusOk, mName);
1099        }
1100    }
1101
1102    private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
1103        private int mType;
1104
1105        GetTypeAnswer(int type) {
1106            mType = type;
1107        }
1108
1109        public void answer(IWifiIface.getTypeCallback cb) {
1110            cb.onValues(mStatusOk, mType);
1111        }
1112    }
1113
1114    // chip configuration
1115
1116    private class ChipMockBase {
1117        public IWifiChip chip;
1118        public int chipId;
1119        public boolean chipModeValid = false;
1120        public int chipModeId = -1000;
1121        public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
1122        public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
1123
1124        public ArrayList<IWifiChip.ChipMode> availableModes;
1125
1126        void initialize() throws Exception {
1127            chip = mock(IWifiChip.class);
1128
1129            interfaceNames.put(IfaceType.STA, new ArrayList<>());
1130            interfaceNames.put(IfaceType.AP, new ArrayList<>());
1131            interfaceNames.put(IfaceType.P2P, new ArrayList<>());
1132            interfaceNames.put(IfaceType.NAN, new ArrayList<>());
1133
1134            interfacesByName.put(IfaceType.STA, new HashMap<>());
1135            interfacesByName.put(IfaceType.AP, new HashMap<>());
1136            interfacesByName.put(IfaceType.P2P, new HashMap<>());
1137            interfacesByName.put(IfaceType.NAN, new HashMap<>());
1138
1139            when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
1140                    mStatusOk);
1141            when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
1142            doAnswer(new GetModeAnswer(this)).when(chip).getMode(
1143                    any(IWifiChip.getModeCallback.class));
1144            GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
1145            doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
1146                    any(IWifiChip.getStaIfaceNamesCallback.class));
1147            doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
1148                    any(IWifiChip.getApIfaceNamesCallback.class));
1149            doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
1150                    any(IWifiChip.getP2pIfaceNamesCallback.class));
1151            doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
1152                    any(IWifiChip.getNanIfaceNamesCallback.class));
1153            GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
1154            doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
1155                    any(IWifiChip.getStaIfaceCallback.class));
1156            doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
1157                    any(IWifiChip.getApIfaceCallback.class));
1158            doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
1159                    any(IWifiChip.getP2pIfaceCallback.class));
1160            doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
1161                    any(IWifiChip.getNanIfaceCallback.class));
1162            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
1163                    anyString());
1164            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
1165                    anyString());
1166            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
1167                    anyString());
1168            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
1169                    anyString());
1170        }
1171    }
1172
1173    // emulate baseline/legacy config:
1174    // mode: STA + NAN || P2P
1175    // mode: NAN
1176    private class BaselineChip extends ChipMockBase {
1177        static final int STA_CHIP_MODE_ID = 0;
1178        static final int AP_CHIP_MODE_ID = 1;
1179
1180        void initialize() throws Exception {
1181            super.initialize();
1182
1183            // chip Id configuration
1184            ArrayList<Integer> chipIds;
1185            chipId = 10;
1186            chipIds = new ArrayList<>();
1187            chipIds.add(chipId);
1188            doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
1189                    any(IWifi.getChipIdsCallback.class));
1190
1191            doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
1192                    any(IWifi.getChipCallback.class));
1193
1194            // initialize dummy chip modes
1195            IWifiChip.ChipMode cm;
1196            IWifiChip.ChipIfaceCombination cic;
1197            IWifiChip.ChipIfaceCombinationLimit cicl;
1198
1199            //   Mode 0: 1xSTA + 1x{P2P,NAN}
1200            //   Mode 1: 1xAP
1201            availableModes = new ArrayList<>();
1202            cm = new IWifiChip.ChipMode();
1203            cm.id = STA_CHIP_MODE_ID;
1204
1205            cic = new IWifiChip.ChipIfaceCombination();
1206
1207            cicl = new IWifiChip.ChipIfaceCombinationLimit();
1208            cicl.maxIfaces = 1;
1209            cicl.types.add(IfaceType.STA);
1210            cic.limits.add(cicl);
1211
1212            cicl = new IWifiChip.ChipIfaceCombinationLimit();
1213            cicl.maxIfaces = 1;
1214            cicl.types.add(IfaceType.P2P);
1215            cicl.types.add(IfaceType.NAN);
1216            cic.limits.add(cicl);
1217            cm.availableCombinations.add(cic);
1218            availableModes.add(cm);
1219
1220            cm = new IWifiChip.ChipMode();
1221            cm.id = AP_CHIP_MODE_ID;
1222            cic = new IWifiChip.ChipIfaceCombination();
1223            cicl = new IWifiChip.ChipIfaceCombinationLimit();
1224            cicl.maxIfaces = 1;
1225            cicl.types.add(IfaceType.AP);
1226            cic.limits.add(cicl);
1227            cm.availableCombinations.add(cic);
1228            availableModes.add(cm);
1229
1230            doAnswer(new GetAvailableModesAnswer(this)).when(chip)
1231                    .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
1232        }
1233    }
1234}
1235