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 com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
20
21import static junit.framework.Assert.assertEquals;
22
23import static org.hamcrest.core.IsEqual.equalTo;
24import static org.junit.Assert.assertFalse;
25import static org.junit.Assert.assertTrue;
26import static org.mockito.Matchers.any;
27import static org.mockito.Matchers.anyInt;
28import static org.mockito.Matchers.anyLong;
29import static org.mockito.Matchers.anyString;
30import static org.mockito.Matchers.eq;
31import static org.mockito.Mockito.doAnswer;
32import static org.mockito.Mockito.inOrder;
33import static org.mockito.Mockito.mock;
34import static org.mockito.Mockito.times;
35import static org.mockito.Mockito.verify;
36import static org.mockito.Mockito.verifyNoMoreInteractions;
37import static org.mockito.Mockito.when;
38
39import android.app.test.MockAnswerUtil;
40import android.hardware.wifi.V1_0.IWifi;
41import android.hardware.wifi.V1_0.IWifiApIface;
42import android.hardware.wifi.V1_0.IWifiChip;
43import android.hardware.wifi.V1_0.IWifiChipEventCallback;
44import android.hardware.wifi.V1_0.IWifiEventCallback;
45import android.hardware.wifi.V1_0.IWifiIface;
46import android.hardware.wifi.V1_0.IWifiNanIface;
47import android.hardware.wifi.V1_0.IWifiP2pIface;
48import android.hardware.wifi.V1_0.IWifiStaIface;
49import android.hardware.wifi.V1_0.IfaceType;
50import android.hardware.wifi.V1_0.WifiStatus;
51import android.hardware.wifi.V1_0.WifiStatusCode;
52import android.hidl.manager.V1_0.IServiceManager;
53import android.hidl.manager.V1_0.IServiceNotification;
54import android.os.Handler;
55import android.os.IHwBinder;
56import android.os.test.TestLooper;
57import android.util.Log;
58
59import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
60
61import org.hamcrest.core.IsNull;
62import org.junit.After;
63import org.junit.Before;
64import org.junit.Rule;
65import org.junit.Test;
66import org.junit.rules.ErrorCollector;
67import org.mockito.ArgumentCaptor;
68import org.mockito.InOrder;
69import org.mockito.Mock;
70import org.mockito.MockitoAnnotations;
71
72import java.io.PrintWriter;
73import java.io.StringWriter;
74import java.util.ArrayList;
75import java.util.HashMap;
76import java.util.HashSet;
77import java.util.Map;
78import java.util.Set;
79
80/**
81 * Unit test harness for HalDeviceManagerTest.
82 */
83public class HalDeviceManagerTest {
84    private HalDeviceManager mDut;
85    @Mock IServiceManager mServiceManagerMock;
86    @Mock IWifi mWifiMock;
87    @Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock;
88    @Mock private Clock mClock;
89    private TestLooper mTestLooper;
90    private Handler mHandler;
91    private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
92            ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
93    private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
94            ArgumentCaptor.forClass(IServiceNotification.Stub.class);
95    private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
96            IWifiEventCallback.class);
97    private InOrder mInOrder;
98    @Rule public ErrorCollector collector = new ErrorCollector();
99    private WifiStatus mStatusOk;
100    private WifiStatus mStatusFail;
101
102    private class HalDeviceManagerSpy extends HalDeviceManager {
103        HalDeviceManagerSpy() {
104            super(mClock);
105        }
106
107        @Override
108        protected IWifi getWifiServiceMockable() {
109            return mWifiMock;
110        }
111
112        @Override
113        protected IServiceManager getServiceManagerMockable() {
114            return mServiceManagerMock;
115        }
116    }
117
118    @Before
119    public void before() throws Exception {
120        MockitoAnnotations.initMocks(this);
121
122        mTestLooper = new TestLooper();
123        mHandler = new Handler(mTestLooper.getLooper());
124
125        // initialize dummy status objects
126        mStatusOk = getStatus(WifiStatusCode.SUCCESS);
127        mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
128
129        when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
130                anyLong())).thenReturn(true);
131        when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
132                any(IServiceNotification.Stub.class))).thenReturn(true);
133        when(mServiceManagerMock.getTransport(
134                eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
135                .thenReturn(IServiceManager.Transport.HWBINDER);
136        when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
137                true);
138        when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
139        when(mWifiMock.start()).thenReturn(mStatusOk);
140        when(mWifiMock.stop()).thenReturn(mStatusOk);
141
142        mDut = new HalDeviceManagerSpy();
143    }
144
145    /**
146     * Print out the dump of the device manager after each test. Not used in test validation
147     * (internal state) - but can help in debugging failed tests.
148     */
149    @After
150    public void after() throws Exception {
151        dumpDut("after: ");
152    }
153
154    //////////////////////////////////////////////////////////////////////////////////////
155    // Chip Independent Tests
156    //////////////////////////////////////////////////////////////////////////////////////
157
158    /**
159     * Test basic startup flow:
160     * - IServiceManager registrations
161     * - IWifi registrations
162     * - IWifi startup delayed
163     * - Start Wi-Fi -> onStart
164     * - Stop Wi-Fi -> onStop
165     */
166    @Test
167    public void testStartStopFlow() throws Exception {
168        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
169        executeAndValidateInitializationSequence();
170        executeAndValidateStartupSequence();
171
172        // act: stop Wi-Fi
173        mDut.stop();
174        mTestLooper.dispatchAll();
175
176        // verify: onStop called
177        mInOrder.verify(mWifiMock).stop();
178        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
179
180        verifyNoMoreInteractions(mManagerStatusListenerMock);
181    }
182
183    /**
184     * Test the service manager notification coming in after
185     * {@link HalDeviceManager#initIWifiIfNecessary()} is already invoked as a part of
186     * {@link HalDeviceManager#initialize()}.
187     */
188    @Test
189    public void testServiceRegisterationAfterInitialize() throws Exception {
190        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
191        executeAndValidateInitializationSequence();
192
193        // This should now be ignored since IWifi is already non-null.
194        mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
195
196        verifyNoMoreInteractions(mManagerStatusListenerMock, mWifiMock, mServiceManagerMock);
197    }
198
199    /**
200     * Validate that multiple callback registrations are called and that duplicate ones are
201     * only called once.
202     */
203    @Test
204    public void testMultipleCallbackRegistrations() throws Exception {
205        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
206        executeAndValidateInitializationSequence();
207
208        // register another 2 callbacks - one of them twice
209        HalDeviceManager.ManagerStatusListener callback1 = mock(
210                HalDeviceManager.ManagerStatusListener.class);
211        HalDeviceManager.ManagerStatusListener callback2 = mock(
212                HalDeviceManager.ManagerStatusListener.class);
213        mDut.registerStatusListener(callback2, mHandler);
214        mDut.registerStatusListener(callback1, mHandler);
215        mDut.registerStatusListener(callback2, mHandler);
216
217        // startup
218        executeAndValidateStartupSequence();
219
220        // verify
221        verify(callback1).onStatusChanged();
222        verify(callback2).onStatusChanged();
223
224        verifyNoMoreInteractions(mManagerStatusListenerMock, callback1, callback2);
225    }
226
227    /**
228     * Validate IWifi death listener and registration flow.
229     */
230    @Test
231    public void testWifiDeathAndRegistration() throws Exception {
232        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
233        executeAndValidateInitializationSequence();
234        executeAndValidateStartupSequence();
235
236        // act: IWifi service death
237        mDeathRecipientCaptor.getValue().serviceDied(0);
238        mTestLooper.dispatchAll();
239
240        // verify: getting onStop
241        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
242
243        // act: service startup
244        mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
245
246        // verify: initialization of IWifi
247        mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
248        mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
249
250        // act: start
251        collector.checkThat(mDut.start(), equalTo(true));
252        mWifiEventCallbackCaptor.getValue().onStart();
253        mTestLooper.dispatchAll();
254
255        // verify: service and callback calls
256        mInOrder.verify(mWifiMock).start();
257        mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
258
259        verifyNoMoreInteractions(mManagerStatusListenerMock);
260    }
261
262    /**
263     * Validate IWifi onFailure causes notification
264     */
265    @Test
266    public void testWifiFail() throws Exception {
267        mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
268        executeAndValidateInitializationSequence();
269        executeAndValidateStartupSequence();
270
271        // act: IWifi failure
272        mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
273        mTestLooper.dispatchAll();
274
275        // verify: getting onStop
276        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
277
278        // act: start again
279        collector.checkThat(mDut.start(), equalTo(true));
280        mWifiEventCallbackCaptor.getValue().onStart();
281        mTestLooper.dispatchAll();
282
283        // verify: service and callback calls
284        mInOrder.verify(mWifiMock).start();
285        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
286
287        verifyNoMoreInteractions(mManagerStatusListenerMock);
288    }
289
290    /**
291     * Validates that when (for some reason) the cache is out-of-sync with the actual chip status
292     * then Wi-Fi is shut-down.
293     *
294     * Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
295     * HDM behavior.
296     */
297    @Test
298    public void testCacheMismatchError() throws Exception {
299        TestChipV1 chipMock = new TestChipV1();
300        chipMock.initialize();
301        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
302                mManagerStatusListenerMock);
303        executeAndValidateInitializationSequence();
304        executeAndValidateStartupSequence();
305
306        InterfaceDestroyedListener staDestroyedListener = mock(
307                InterfaceDestroyedListener.class);
308        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
309                HalDeviceManager.InterfaceAvailableForRequestListener.class);
310
311        InterfaceDestroyedListener nanDestroyedListener = mock(
312                InterfaceDestroyedListener.class);
313        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
314                HalDeviceManager.InterfaceAvailableForRequestListener.class);
315
316        InOrder availInOrder = inOrder(staAvailListener, nanAvailListener);
317
318        // Request STA
319        IWifiIface staIface = validateInterfaceSequence(chipMock,
320                false, // chipModeValid
321                -1000, // chipModeId (only used if chipModeValid is true)
322                IfaceType.STA, // ifaceTypeToCreate
323                "wlan0", // ifaceName
324                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
325                false, // high priority
326                null, // tearDownList
327                staDestroyedListener, // destroyedListener
328                staAvailListener // availableListener
329        );
330        availInOrder.verify(staAvailListener).onAvailabilityChanged(false);
331
332        // Request NAN
333        IWifiIface nanIface = validateInterfaceSequence(chipMock,
334                true, // chipModeValid
335                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
336                IfaceType.NAN, // ifaceTypeToCreate
337                "wlan0", // ifaceName
338                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
339                false, // high priority (but irrelevant)
340                null, // tearDownList
341                nanDestroyedListener, // destroyedListener
342                nanAvailListener // availableListener
343        );
344        availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
345
346        // fiddle with the "chip" by removing the STA
347        chipMock.interfaceNames.get(IfaceType.STA).remove("wlan0");
348
349        // now try to request another NAN
350        IWifiIface nanIface2 = mDut.createNanIface(nanDestroyedListener, mHandler);
351        collector.checkThat("NAN can't be created", nanIface2, IsNull.nullValue());
352
353        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
354                mHandler);
355        mTestLooper.dispatchAll();
356
357        // extra (apparently duplicate) call since everything was cleaned-up once a cache mismatch
358        // was detected - so this is a call on a new registration
359        availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
360
361        // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
362        // registered (even if they seem out-of-sync to chip)
363        verify(mWifiMock, times(2)).stop();
364        verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
365        verify(staDestroyedListener).onDestroyed(getName(staIface));
366        verify(nanDestroyedListener).onDestroyed(getName(nanIface));
367
368        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
369                nanDestroyedListener, nanAvailListener);
370    }
371
372    /**
373     * Validates that a duplicate registration of the same InterfaceAvailableForRequestListener
374     * listener will result in a single callback.
375     *
376     * Also validates that get an immediate call on registration if available.
377     *
378     * Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
379     * HDM behavior.
380     */
381    @Test
382    public void testDuplicateAvailableRegistrations() throws Exception {
383        TestChipV1 chipMock = new TestChipV1();
384        chipMock.initialize();
385        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
386                mManagerStatusListenerMock);
387        executeAndValidateInitializationSequence();
388        executeAndValidateStartupSequence();
389
390        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
391                HalDeviceManager.InterfaceAvailableForRequestListener.class);
392
393        // get STA interface
394        IWifiIface staIface = validateInterfaceSequence(chipMock,
395                false, // chipModeValid
396                -1000, // chipModeId (only used if chipModeValid is true)
397                IfaceType.STA, // ifaceTypeToCreate
398                "wlan0", // ifaceName
399                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
400                false, // high priority
401                null, // tearDownList
402                null, // destroyedListener
403                null // availableListener
404        );
405        collector.checkThat("STA created", staIface, IsNull.notNullValue());
406
407        // act: register the same listener twice
408        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
409                mHandler);
410        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
411                mHandler);
412        mTestLooper.dispatchAll();
413
414        verify(staAvailListener).onAvailabilityChanged(false);
415
416        // remove STA interface -> should trigger callbacks
417        mDut.removeIface(staIface);
418        mTestLooper.dispatchAll();
419
420        // verify: only a single trigger
421        verify(staAvailListener).onAvailabilityChanged(true);
422
423        verifyNoMoreInteractions(staAvailListener);
424    }
425
426    /**
427     * Validate that when no chip info is found an empty list is returned.
428     */
429    @Test
430    public void testGetSupportedIfaceTypesError() throws Exception {
431        // try API
432        Set<Integer> results = mDut.getSupportedIfaceTypes();
433
434        // verify results
435        assertEquals(0, results.size());
436    }
437
438    /**
439     * Test start HAL can retry upon failure.
440     *
441     * Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
442     * HDM behavior.
443     */
444    @Test
445    public void testStartHalRetryUponNotAvailableFailure() throws Exception {
446        // Override the stubbing for mWifiMock in before().
447        when(mWifiMock.start())
448                .thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE))
449                .thenReturn(mStatusOk);
450
451        TestChipV1 chipMock = new TestChipV1();
452        chipMock.initialize();
453        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
454                mManagerStatusListenerMock);
455        executeAndValidateInitializationSequence();
456        executeAndValidateStartupSequence(2, true);
457    }
458
459    /**
460     * Test start HAL fails after multiple retry failures.
461     *
462     * Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
463     * HDM behavior.
464     */
465    @Test
466    public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception {
467        // Override the stubbing for mWifiMock in before().
468        when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE));
469
470        TestChipV1 chipMock = new TestChipV1();
471        chipMock.initialize();
472        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
473        executeAndValidateInitializationSequence();
474        executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false);
475    }
476
477    /**
478     * Test start HAL fails after multiple retry failures.
479     *
480     * Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
481     * HDM behavior.
482     */
483    @Test
484    public void testStartHalRetryFailUponTrueFailure() throws Exception {
485        // Override the stubbing for mWifiMock in before().
486        when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN));
487
488        TestChipV1 chipMock = new TestChipV1();
489        chipMock.initialize();
490        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
491        executeAndValidateInitializationSequence();
492        executeAndValidateStartupSequence(1, false);
493    }
494
495    /**
496     * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
497     * the VINTF.
498     */
499    @Test
500    public void testIsSupportedTrue() throws Exception {
501        mInOrder = inOrder(mServiceManagerMock, mWifiMock);
502        executeAndValidateInitializationSequence();
503        assertTrue(mDut.isSupported());
504    }
505
506    /**
507     * Validate that isSupported() returns false when IServiceManager does not find the vendor HAL
508     * daemon in the VINTF.
509     */
510    @Test
511    public void testIsSupportedFalse() throws Exception {
512        when(mServiceManagerMock.getTransport(
513                eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
514                .thenReturn(IServiceManager.Transport.EMPTY);
515        mInOrder = inOrder(mServiceManagerMock, mWifiMock);
516        executeAndValidateInitializationSequence(false);
517        assertFalse(mDut.isSupported());
518    }
519
520    //////////////////////////////////////////////////////////////////////////////////////
521    // Chip Specific Tests - but should work on all chips!
522    // (i.e. add copies for each test chip)
523    //////////////////////////////////////////////////////////////////////////////////////
524
525    // TestChipV1
526
527    /**
528     * Validate creation of STA interface from blank start-up. The remove interface.
529     */
530    @Test
531    public void testCreateStaInterfaceNoInitModeTestChipV1() throws Exception {
532        runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.STA, "wlan0",
533                TestChipV1.STA_CHIP_MODE_ID, false);
534    }
535
536    /**
537     * Validate creation of AP interface from blank start-up. The remove interface.
538     */
539    @Test
540    public void testCreateApInterfaceNoInitModeTestChipV1() throws Exception {
541        runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.AP, "wlan0",
542                TestChipV1.AP_CHIP_MODE_ID, false);
543    }
544
545    /**
546     * Validate creation of P2P interface from blank start-up. The remove interface.
547     */
548    @Test
549    public void testCreateP2pInterfaceNoInitModeTestChipV1() throws Exception {
550        runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.P2P, "p2p0",
551                TestChipV1.STA_CHIP_MODE_ID, false);
552    }
553
554    /**
555     * Validate creation of NAN interface from blank start-up. The remove interface.
556     */
557    @Test
558    public void testCreateNanInterfaceNoInitModeTestChipV1() throws Exception {
559        runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.NAN, "wlan0",
560                TestChipV1.STA_CHIP_MODE_ID, false);
561    }
562
563    // TestChipV2
564
565    /**
566     * Validate creation of STA interface from blank start-up. The remove interface.
567     */
568    @Test
569    public void testCreateStaInterfaceNoInitModeTestChipV2() throws Exception {
570        // Note: we expected 2 available callbacks since we now have 2 STAs possible. So
571        // we get callback 1 after creating the first STA (since we can create another STA),
572        // and we get callback 2 after destroying the first STA (since we can create another STA -
573        // as expected).
574        runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.STA, "wlan0",
575                TestChipV2.CHIP_MODE_ID, true);
576    }
577
578    /**
579     * Validate creation of AP interface from blank start-up. The remove interface.
580     */
581    @Test
582    public void testCreateApInterfaceNoInitModeTestChipV2() throws Exception {
583        runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.AP, "wlan0",
584                TestChipV2.CHIP_MODE_ID, false);
585    }
586
587    /**
588     * Validate creation of P2P interface from blank start-up. The remove interface.
589     */
590    @Test
591    public void testCreateP2pInterfaceNoInitModeTestChipV2() throws Exception {
592        runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.P2P, "p2p0",
593                TestChipV2.CHIP_MODE_ID, false);
594    }
595
596    /**
597     * Validate creation of NAN interface from blank start-up. The remove interface.
598     */
599    @Test
600    public void testCreateNanInterfaceNoInitModeTestChipV2() throws Exception {
601        runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.NAN, "wlan0",
602                TestChipV2.CHIP_MODE_ID, false);
603    }
604
605    // TestChipV3
606
607    /**
608     * Validate creation of STA interface from blank start-up. The remove interface.
609     */
610    @Test
611    public void testCreateStaInterfaceNoInitModeTestChipV3() throws Exception {
612        // Note: we expected 2 available callbacks since we now have 2 STAs possible. So
613        // we get callback 1 after creating the first STA (since we can create another STA),
614        // and we get callback 2 after destroying the first STA (since we can create another STA -
615        // as expected).
616        runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.STA, "wlan0",
617                TestChipV3.CHIP_MODE_ID, true);
618    }
619
620    /**
621     * Validate creation of AP interface from blank start-up. The remove interface.
622     */
623    @Test
624    public void testCreateApInterfaceNoInitModeTestChipV3() throws Exception {
625        runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.AP, "wlan0",
626                TestChipV3.CHIP_MODE_ID, false);
627    }
628
629    /**
630     * Validate creation of P2P interface from blank start-up. The remove interface.
631     */
632    @Test
633    public void testCreateP2pInterfaceNoInitModeTestChipV3() throws Exception {
634        runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.P2P, "p2p0",
635                TestChipV3.CHIP_MODE_ID, false);
636    }
637
638    /**
639     * Validate creation of NAN interface from blank start-up. The remove interface.
640     */
641    @Test
642    public void testCreateNanInterfaceNoInitModeTestChipV3() throws Exception {
643        runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.NAN, "wlan0",
644                TestChipV3.CHIP_MODE_ID, false);
645    }
646
647    // TestChipV4
648
649    /**
650     * Validate creation of STA interface from blank start-up. The remove interface.
651     */
652    @Test
653    public void testCreateStaInterfaceNoInitModeTestChipV4() throws Exception {
654        runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.STA, "wlan0",
655                TestChipV4.CHIP_MODE_ID, false);
656    }
657
658    /**
659     * Validate creation of AP interface from blank start-up. The remove interface.
660     */
661    @Test
662    public void testCreateApInterfaceNoInitModeTestChipV4() throws Exception {
663        runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.AP, "wlan0",
664                TestChipV4.CHIP_MODE_ID, false);
665    }
666
667    /**
668     * Validate creation of P2P interface from blank start-up. The remove interface.
669     */
670    @Test
671    public void testCreateP2pInterfaceNoInitModeTestChipV4() throws Exception {
672        runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.P2P, "p2p0",
673                TestChipV4.CHIP_MODE_ID, false);
674    }
675
676    /**
677     * Validate creation of NAN interface from blank start-up. The remove interface.
678     */
679    @Test
680    public void testCreateNanInterfaceNoInitModeTestChipV4() throws Exception {
681        runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.NAN, "wlan0",
682                TestChipV4.CHIP_MODE_ID, false);
683    }
684
685    //////////////////////////////////////////////////////////////////////////////////////
686    // TestChipV1 Specific Tests
687    //////////////////////////////////////////////////////////////////////////////////////
688
689    /**
690     * Validate creation of AP interface when in STA mode - but with no interface created. Expect
691     * a change in chip mode.
692     */
693    @Test
694    public void testCreateApWithStaModeUpTestChipV1() throws Exception {
695        final String name = "wlan0";
696
697        TestChipV1 chipMock = new TestChipV1();
698        chipMock.initialize();
699        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
700                mManagerStatusListenerMock);
701        executeAndValidateInitializationSequence();
702        executeAndValidateStartupSequence();
703
704        InterfaceDestroyedListener idl = mock(
705                InterfaceDestroyedListener.class);
706        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
707                HalDeviceManager.InterfaceAvailableForRequestListener.class);
708
709        IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
710                true, // chipModeValid
711                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
712                IfaceType.AP, // ifaceTypeToCreate
713                name, // ifaceName
714                TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
715                false, // high priority (but irrelevant)
716                null, // tearDownList
717                idl, // destroyedListener
718                iafrl // availableListener
719        );
720        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
721
722        verify(iafrl).onAvailabilityChanged(false);
723
724        // act: stop Wi-Fi
725        mDut.stop();
726        mTestLooper.dispatchAll();
727
728        // verify: callback triggered
729        verify(idl).onDestroyed(getName(iface));
730        verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
731
732        verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
733    }
734
735    /**
736     * Validate creation of AP interface when in STA mode with a single STA iface created.
737     * Expect a change in chip mode.
738     */
739    @Test
740    public void testCreateApWithStIfaceUpTestChipV1UsingNoHandlerListeners() throws Exception {
741        TestChipV1 chipMock = new TestChipV1();
742        chipMock.initialize();
743
744        InterfaceDestroyedListener staIdl = mock(
745                InterfaceDestroyedListener.class);
746        HalDeviceManager.InterfaceAvailableForRequestListener staIafrl = mock(
747                HalDeviceManager.InterfaceAvailableForRequestListener.class);
748        InterfaceDestroyedListener apIdl = mock(
749                InterfaceDestroyedListener.class);
750        HalDeviceManager.InterfaceAvailableForRequestListener apIafrl = mock(
751                HalDeviceManager.InterfaceAvailableForRequestListener.class);
752
753        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
754                mManagerStatusListenerMock, staIdl, staIafrl, apIdl, apIafrl);
755        executeAndValidateInitializationSequence();
756
757        // Register listener & start Wi-Fi
758        mDut.registerStatusListener(mManagerStatusListenerMock, null);
759        assertTrue(mDut.start());
760        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
761
762        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staIafrl, null);
763        mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apIafrl, null);
764
765        mInOrder.verify(staIafrl).onAvailabilityChanged(true);
766        mInOrder.verify(apIafrl).onAvailabilityChanged(true);
767
768        // Create STA Iface first.
769        IWifiStaIface staIface = mock(IWifiStaIface.class);
770        doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
771                any(IWifiIface.getNameCallback.class));
772        doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
773                any(IWifiIface.getTypeCallback.class));
774        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
775                chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
776        assertEquals(staIface, mDut.createStaIface(false, staIdl, null));
777
778        mInOrder.verify(chipMock.chip).configureChip(TestChipV1.STA_CHIP_MODE_ID);
779        mInOrder.verify(staIafrl).onAvailabilityChanged(false);
780
781        // Now Create AP Iface.
782        IWifiApIface apIface = mock(IWifiApIface.class);
783        doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
784                any(IWifiIface.getNameCallback.class));
785        doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
786                any(IWifiIface.getTypeCallback.class));
787        doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
788                chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
789        assertEquals(apIface, mDut.createApIface(apIdl, null));
790
791        mInOrder.verify(chipMock.chip).removeStaIface(getName(staIface));
792        mInOrder.verify(staIdl).onDestroyed(getName(staIface));
793        mInOrder.verify(chipMock.chip).configureChip(TestChipV1.AP_CHIP_MODE_ID);
794        mInOrder.verify(apIafrl).onAvailabilityChanged(false);
795        mInOrder.verify(staIafrl).onAvailabilityChanged(true);
796
797        // Stop Wi-Fi
798        mDut.stop();
799
800        mInOrder.verify(mWifiMock).stop();
801        mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
802        mInOrder.verify(apIdl).onDestroyed(getName(apIface));
803
804        verifyNoMoreInteractions(mManagerStatusListenerMock, staIdl, staIafrl, apIdl, apIafrl);
805    }
806
807    /**
808     * Validate creation of AP interface when in AP mode - but with no interface created. Expect
809     * no change in chip mode.
810     */
811    @Test
812    public void testCreateApWithApModeUpTestChipV1() throws Exception {
813        final String name = "wlan0";
814
815        TestChipV1 chipMock = new TestChipV1();
816        chipMock.initialize();
817        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
818                mManagerStatusListenerMock);
819        executeAndValidateInitializationSequence();
820        executeAndValidateStartupSequence();
821
822        InterfaceDestroyedListener idl = mock(
823                InterfaceDestroyedListener.class);
824        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
825                HalDeviceManager.InterfaceAvailableForRequestListener.class);
826
827        IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
828                true, // chipModeValid
829                TestChipV1.AP_CHIP_MODE_ID, // chipModeId
830                IfaceType.AP, // ifaceTypeToCreate
831                name, // ifaceName
832                TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
833                false, // high priority (but irrelevant)
834                null, // tearDownList
835                idl, // destroyedListener
836                iafrl // availableListener
837        );
838        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
839
840        verify(iafrl).onAvailabilityChanged(false);
841
842        // act: stop Wi-Fi
843        mDut.stop();
844        mTestLooper.dispatchAll();
845
846        // verify: callback triggered
847        verify(idl).onDestroyed(getName(iface));
848        verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
849
850        verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
851    }
852
853    /**
854     * Validate AP up/down creation of AP interface when a STA already created. Expect:
855     * - STA created
856     * - P2P created
857     * - When AP requested:
858     *   - STA & P2P torn down
859     *   - AP created
860     * - P2P creation refused
861     * - Request STA: will tear down AP
862     * - When AP destroyed:
863     *   - Get p2p available listener callback
864     *   - Can create P2P when requested
865     * - Create P2P
866     * - Request NAN: will get refused
867     * - Tear down P2P:
868     *    - should get nan available listener callback
869     *    - Can create NAN when requested
870     */
871    @Test
872    public void testCreateSameAndDiffPrioritiesTestChipV1() throws Exception {
873        TestChipV1 chipMock = new TestChipV1();
874        chipMock.initialize();
875        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
876                mManagerStatusListenerMock);
877        executeAndValidateInitializationSequence();
878        executeAndValidateStartupSequence();
879
880        InterfaceDestroyedListener staDestroyedListener = mock(
881                InterfaceDestroyedListener.class);
882        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
883                HalDeviceManager.InterfaceAvailableForRequestListener.class);
884
885        InterfaceDestroyedListener staDestroyedListener2 = mock(
886                InterfaceDestroyedListener.class);
887
888        InterfaceDestroyedListener apDestroyedListener = mock(
889                InterfaceDestroyedListener.class);
890        HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
891                HalDeviceManager.InterfaceAvailableForRequestListener.class);
892
893        InterfaceDestroyedListener p2pDestroyedListener = mock(
894                InterfaceDestroyedListener.class);
895        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
896                HalDeviceManager.InterfaceAvailableForRequestListener.class);
897
898        InterfaceDestroyedListener p2pDestroyedListener2 = mock(
899                InterfaceDestroyedListener.class);
900
901        InterfaceDestroyedListener nanDestroyedListener = mock(
902                InterfaceDestroyedListener.class);
903        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
904                HalDeviceManager.InterfaceAvailableForRequestListener.class);
905
906        InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
907                nanAvailListener);
908
909        // register listeners for interface availability
910        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
911                mHandler);
912        mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
913        mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
914                mHandler);
915        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
916                mHandler);
917        mTestLooper.dispatchAll();
918
919        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
920        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
921        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
922        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
923
924        // Request STA
925        IWifiIface staIface = validateInterfaceSequence(chipMock,
926                false, // chipModeValid
927                -1000, // chipModeId (only used if chipModeValid is true)
928                IfaceType.STA, // ifaceTypeToCreate
929                "wlan0", // ifaceName
930                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
931                false, // high priority
932                null, // tearDownList
933                staDestroyedListener, // destroyedListener
934                null // availableListener
935        );
936        collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
937
938        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
939
940        // request STA2: should fail
941        IWifiIface staIface2 = mDut.createStaIface(false, null, null);
942        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
943
944        // register additional InterfaceDestroyedListeners - including a duplicate (verify that
945        // only called once!)
946        mDut.registerDestroyedListener(staIface, staDestroyedListener2, mHandler);
947        mDut.registerDestroyedListener(staIface, staDestroyedListener, mHandler);
948
949        // Request P2P
950        IWifiIface p2pIface = validateInterfaceSequence(chipMock,
951                true, // chipModeValid
952                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
953                IfaceType.P2P, // ifaceTypeToCreate
954                "p2p0", // ifaceName
955                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
956                false, // high priority (but irrelevant)
957                null, // tearDownList
958                p2pDestroyedListener, // destroyedListener
959                null // availableListener
960        );
961        collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
962
963        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
964        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
965
966        // Request AP
967        IWifiIface apIface = validateInterfaceSequence(chipMock,
968                true, // chipModeValid
969                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
970                IfaceType.AP, // ifaceTypeToCreate
971                "wlan0", // ifaceName
972                TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
973                false, // high priority (but irrelevant)
974                new IWifiIface[]{staIface, p2pIface}, // tearDownList
975                apDestroyedListener, // destroyedListener
976                null, // availableListener
977                // destroyedInterfacesDestroyedListeners...
978                new InterfaceDestroyedListenerWithIfaceName(
979                        getName(staIface), staDestroyedListener),
980                new InterfaceDestroyedListenerWithIfaceName(
981                        getName(staIface), staDestroyedListener2),
982                new InterfaceDestroyedListenerWithIfaceName(
983                        getName(p2pIface), p2pDestroyedListener)
984        );
985        collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue());
986
987        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
988        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
989
990        // request AP2: should fail
991        IWifiIface apIface2 = mDut.createApIface(null, null);
992        collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
993
994        // Request P2P: expect failure
995        p2pIface = mDut.createP2pIface(p2pDestroyedListener, mHandler);
996        collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue());
997
998        // Request STA: expect success
999        staIface = validateInterfaceSequence(chipMock,
1000                true, // chipModeValid
1001                TestChipV1.AP_CHIP_MODE_ID, // chipModeId
1002                IfaceType.STA, // ifaceTypeToCreate
1003                "wlan0", // ifaceName
1004                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
1005                false, // high priority
1006                null, // tearDownList
1007                staDestroyedListener, // destroyedListener
1008                null, // availableListener
1009                // destroyedInterfacesDestroyedListeners...
1010                new InterfaceDestroyedListenerWithIfaceName(
1011                        getName(apIface), apDestroyedListener)
1012        );
1013        collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
1014
1015        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1016        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1017        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1018        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1019
1020        mTestLooper.dispatchAll();
1021        verify(apDestroyedListener).onDestroyed(getName(apIface));
1022
1023        // Request P2P: expect success now
1024        p2pIface = validateInterfaceSequence(chipMock,
1025                true, // chipModeValid
1026                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
1027                IfaceType.P2P, // ifaceTypeToCreate
1028                "p2p0", // ifaceName
1029                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
1030                false, // high priority (but irrelevant)
1031                null, // tearDownList
1032                p2pDestroyedListener2, // destroyedListener
1033                null // availableListener
1034        );
1035
1036        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
1037        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1038
1039        // Request NAN: should fail
1040        IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, mHandler);
1041        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
1042                mHandler);
1043        collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
1044
1045        // Tear down P2P
1046        mDut.removeIface(p2pIface);
1047        mTestLooper.dispatchAll();
1048
1049        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1050        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1051        verify(chipMock.chip, times(2)).removeP2pIface("p2p0");
1052        verify(p2pDestroyedListener2).onDestroyed(getName(p2pIface));
1053
1054        // Should now be able to request and get NAN
1055        nanIface = validateInterfaceSequence(chipMock,
1056                true, // chipModeValid
1057                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
1058                IfaceType.NAN, // ifaceTypeToCreate
1059                "wlan0", // ifaceName
1060                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
1061                false, // high priority (but irrelevant)
1062                null, // tearDownList
1063                nanDestroyedListener, // destroyedListener
1064                nanAvailListener // availableListener
1065        );
1066        collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
1067
1068        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1069
1070        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
1071                staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener,
1072                nanDestroyedListener, nanAvailListener, p2pDestroyedListener2);
1073    }
1074
1075    /**
1076     * Validate P2P and NAN interactions. Expect:
1077     * - STA created
1078     * - NAN created
1079     * - When P2P requested:
1080     *   - NAN torn down
1081     *   - P2P created
1082     * - NAN creation refused
1083     * - When P2P destroyed:
1084     *   - get nan available listener
1085     *   - Can create NAN when requested
1086     */
1087    @Test
1088    public void testP2pAndNanInteractionsTestChipV1() throws Exception {
1089        runP2pAndNanExclusiveInteractionsTestChip(new TestChipV1(), TestChipV1.STA_CHIP_MODE_ID);
1090    }
1091
1092    /**
1093     * Validates that trying to allocate a STA and then another STA fails. Only one STA at a time
1094     * is permitted (by TestChipV1 chip).
1095     */
1096    @Test
1097    public void testDuplicateStaRequestsTestChipV1() throws Exception {
1098        TestChipV1 chipMock = new TestChipV1();
1099        chipMock.initialize();
1100        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1101                mManagerStatusListenerMock);
1102        executeAndValidateInitializationSequence();
1103        executeAndValidateStartupSequence();
1104
1105        InterfaceDestroyedListener staDestroyedListener1 = mock(
1106                InterfaceDestroyedListener.class);
1107        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener1 = mock(
1108                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1109
1110        InterfaceDestroyedListener staDestroyedListener2 = mock(
1111                InterfaceDestroyedListener.class);
1112
1113        // get STA interface
1114        IWifiIface staIface1 = validateInterfaceSequence(chipMock,
1115                false, // chipModeValid
1116                -1000, // chipModeId (only used if chipModeValid is true)
1117                IfaceType.STA, // ifaceTypeToCreate
1118                "wlan0", // ifaceName
1119                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
1120                false, // high priority
1121                null, // tearDownList
1122                staDestroyedListener1, // destroyedListener
1123                staAvailListener1 // availableListener
1124        );
1125        collector.checkThat("STA created", staIface1, IsNull.notNullValue());
1126
1127        verify(staAvailListener1).onAvailabilityChanged(false);
1128
1129        // get STA interface again
1130        IWifiIface staIface2 = mDut.createStaIface(false, staDestroyedListener2, mHandler);
1131        collector.checkThat("STA created", staIface2, IsNull.nullValue());
1132
1133        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener1,
1134                staAvailListener1, staDestroyedListener2);
1135    }
1136
1137    /**
1138     * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
1139     */
1140    @Test
1141    public void testGetSupportedIfaceTypesAllTestChipV1() throws Exception {
1142        TestChipV1 chipMock = new TestChipV1();
1143        chipMock.initialize();
1144        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1145                mManagerStatusListenerMock);
1146        executeAndValidateInitializationSequence();
1147        executeAndValidateStartupSequence();
1148
1149        // try API
1150        Set<Integer> results = mDut.getSupportedIfaceTypes();
1151
1152        // verify results
1153        Set<Integer> correctResults = new HashSet<>();
1154        correctResults.add(IfaceType.AP);
1155        correctResults.add(IfaceType.STA);
1156        correctResults.add(IfaceType.P2P);
1157        correctResults.add(IfaceType.NAN);
1158
1159        assertEquals(correctResults, results);
1160    }
1161
1162    /**
1163     * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
1164     */
1165    @Test
1166    public void testGetSupportedIfaceTypesOneChipTestChipV1() throws Exception {
1167        TestChipV1 chipMock = new TestChipV1();
1168        chipMock.initialize();
1169        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1170                mManagerStatusListenerMock);
1171        executeAndValidateInitializationSequence();
1172        executeAndValidateStartupSequence();
1173
1174        // try API
1175        Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
1176
1177        // verify results
1178        Set<Integer> correctResults = new HashSet<>();
1179        correctResults.add(IfaceType.AP);
1180        correctResults.add(IfaceType.STA);
1181        correctResults.add(IfaceType.P2P);
1182        correctResults.add(IfaceType.NAN);
1183
1184        assertEquals(correctResults, results);
1185    }
1186
1187    //////////////////////////////////////////////////////////////////////////////////////
1188    // TestChipV2 Specific Tests
1189    //////////////////////////////////////////////////////////////////////////////////////
1190
1191    /**
1192     * Validate a flow sequence for test chip 2:
1193     * - create STA
1194     * - create P2P
1195     * - request NAN: failure
1196     * - create AP
1197     * - create STA: will get refused
1198     * - create AP: will get refused
1199     * - tear down AP
1200     * - create STA
1201     * - create STA: will get refused
1202     * - create AP: should get created and the last created STA should get destroyed
1203     * - tear down P2P
1204     * - create NAN
1205     */
1206    @Test
1207    public void testInterfaceCreationFlowTestChipV2() throws Exception {
1208        TestChipV2 chipMock = new TestChipV2();
1209        chipMock.initialize();
1210        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1211                mManagerStatusListenerMock);
1212        executeAndValidateInitializationSequence();
1213        executeAndValidateStartupSequence();
1214
1215        InterfaceDestroyedListener staDestroyedListener = mock(
1216                InterfaceDestroyedListener.class);
1217        InterfaceDestroyedListener staDestroyedListener2 = mock(
1218                InterfaceDestroyedListener.class);
1219        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
1220                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1221
1222        InterfaceDestroyedListener apDestroyedListener = mock(
1223                InterfaceDestroyedListener.class);
1224        HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
1225                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1226
1227        InterfaceDestroyedListener p2pDestroyedListener = mock(
1228                InterfaceDestroyedListener.class);
1229        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
1230                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1231
1232        InterfaceDestroyedListener nanDestroyedListener = mock(
1233                InterfaceDestroyedListener.class);
1234        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
1235                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1236
1237        InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
1238                nanAvailListener);
1239
1240        // register listeners for interface availability
1241        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
1242                mHandler);
1243        mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
1244        mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
1245                mHandler);
1246        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
1247                mHandler);
1248        mTestLooper.dispatchAll();
1249
1250        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1251        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1252        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1253        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1254
1255        // create STA
1256        when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
1257        IWifiIface staIface = validateInterfaceSequence(chipMock,
1258                false, // chipModeValid
1259                -1000, // chipModeId (only used if chipModeValid is true)
1260                IfaceType.STA, // ifaceTypeToCreate
1261                "wlan0", // ifaceName
1262                TestChipV2.CHIP_MODE_ID, // finalChipMode
1263                false, // high priority
1264                null, // tearDownList
1265                staDestroyedListener, // destroyedListener
1266                null // availableListener (already registered)
1267        );
1268        collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
1269
1270        // create P2P
1271        IWifiIface p2pIface = validateInterfaceSequence(chipMock,
1272                true, // chipModeValid
1273                TestChipV2.CHIP_MODE_ID, // chipModeId
1274                IfaceType.P2P, // ifaceTypeToCreate
1275                "p2p0", // ifaceName
1276                TestChipV2.CHIP_MODE_ID, // finalChipMode
1277                false, // high priority (but irrelevant)
1278                null, // tearDownList
1279                p2pDestroyedListener, // destroyedListener
1280                null // availableListener (already registered)
1281        );
1282        collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
1283
1284        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
1285        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1286
1287        // request NAN: should fail
1288        IWifiIface nanIface = mDut.createNanIface(null, null);
1289        collector.checkThat("NAN should not be created", nanIface, IsNull.nullValue());
1290
1291        // create AP
1292        IWifiIface apIface = validateInterfaceSequence(chipMock,
1293                true, // chipModeValid
1294                TestChipV2.CHIP_MODE_ID, // chipModeId
1295                IfaceType.AP, // ifaceTypeToCreate
1296                "wlan1", // ifaceName
1297                TestChipV2.CHIP_MODE_ID, // finalChipMode
1298                false, // high priority (but irrelevant)
1299                null, // tearDownList
1300                apDestroyedListener, // destroyedListener
1301                null // availableListener (already registered)
1302        );
1303        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
1304
1305        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
1306        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1307
1308        // request STA2: should fail
1309        IWifiIface staIface2 = mDut.createStaIface(false, null, null);
1310        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1311
1312        // request AP2: should fail
1313        IWifiIface apIface2 = mDut.createApIface(null, null);
1314        collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
1315
1316        // tear down AP
1317        mDut.removeIface(apIface);
1318        mTestLooper.dispatchAll();
1319
1320        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1321        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1322        verify(chipMock.chip).removeApIface("wlan1");
1323        verify(apDestroyedListener).onDestroyed(getName(apIface));
1324
1325        // create STA2: using a later clock
1326        when(mClock.getUptimeSinceBootMillis()).thenReturn(20L);
1327        staIface2 = validateInterfaceSequence(chipMock,
1328                true, // chipModeValid
1329                TestChipV2.CHIP_MODE_ID, // chipModeId
1330                IfaceType.STA, // ifaceTypeToCreate
1331                "wlan1", // ifaceName
1332                TestChipV2.CHIP_MODE_ID, // finalChipMode
1333                false, // high priority
1334                null, // tearDownList
1335                staDestroyedListener2, // destroyedListener
1336                null // availableListener (already registered)
1337        );
1338        collector.checkThat("STA 2 interface wasn't created", staIface2, IsNull.notNullValue());
1339
1340        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1341
1342        // request STA3: should fail
1343        IWifiIface staIface3 = mDut.createStaIface(false, null, null);
1344        collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
1345
1346        // create AP - this will destroy the last STA created, i.e. STA2
1347        apIface = validateInterfaceSequence(chipMock,
1348                true, // chipModeValid
1349                TestChipV2.CHIP_MODE_ID, // chipModeId
1350                IfaceType.AP, // ifaceTypeToCreate
1351                "wlan1", // ifaceName
1352                TestChipV2.CHIP_MODE_ID, // finalChipMode
1353                false, // high priority (but irrelevant)
1354                null, // tearDownList
1355                apDestroyedListener, // destroyedListener
1356                null, // availableListener (already registered),
1357                // destroyedInterfacesDestroyedListeners...
1358                new InterfaceDestroyedListenerWithIfaceName(
1359                        getName(staIface2), staDestroyedListener2)
1360        );
1361        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
1362
1363        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
1364
1365        // tear down P2P
1366        mDut.removeIface(p2pIface);
1367        mTestLooper.dispatchAll();
1368
1369        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1370        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1371        verify(chipMock.chip).removeP2pIface("p2p0");
1372        verify(p2pDestroyedListener).onDestroyed(getName(p2pIface));
1373
1374        // create NAN
1375        nanIface = validateInterfaceSequence(chipMock,
1376                true, // chipModeValid
1377                TestChipV2.CHIP_MODE_ID, // chipModeId
1378                IfaceType.NAN, // ifaceTypeToCreate
1379                "wlan0", // ifaceName
1380                TestChipV2.CHIP_MODE_ID, // finalChipMode
1381                false, // high priority (but irrelevant)
1382                null, // tearDownList
1383                nanDestroyedListener, // destroyedListener
1384                null // availableListener (already registered)
1385        );
1386        collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
1387
1388        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1389
1390        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
1391                staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
1392                nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
1393                nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
1394                nanAvailListener);
1395    }
1396
1397    /**
1398     * Validate P2P and NAN interactions. Expect:
1399     * - STA created
1400     * - NAN created
1401     * - When P2P requested:
1402     *   - NAN torn down
1403     *   - P2P created
1404     * - NAN creation refused
1405     * - When P2P destroyed:
1406     *   - get nan available listener
1407     *   - Can create NAN when requested
1408     */
1409    @Test
1410    public void testP2pAndNanInteractionsTestChipV2() throws Exception {
1411        runP2pAndNanExclusiveInteractionsTestChip(new TestChipV2(), TestChipV2.CHIP_MODE_ID);
1412    }
1413
1414    /**
1415     * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
1416     */
1417    @Test
1418    public void testGetSupportedIfaceTypesAllTestChipV2() throws Exception {
1419        TestChipV2 chipMock = new TestChipV2();
1420        chipMock.initialize();
1421        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1422                mManagerStatusListenerMock);
1423        executeAndValidateInitializationSequence();
1424        executeAndValidateStartupSequence();
1425
1426        // try API
1427        Set<Integer> results = mDut.getSupportedIfaceTypes();
1428
1429        // verify results
1430        Set<Integer> correctResults = new HashSet<>();
1431        correctResults.add(IfaceType.AP);
1432        correctResults.add(IfaceType.STA);
1433        correctResults.add(IfaceType.P2P);
1434        correctResults.add(IfaceType.NAN);
1435
1436        assertEquals(correctResults, results);
1437    }
1438
1439    /**
1440     * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
1441     */
1442    @Test
1443    public void testGetSupportedIfaceTypesOneChipTestChipV2() throws Exception {
1444        TestChipV2 chipMock = new TestChipV2();
1445        chipMock.initialize();
1446        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1447                mManagerStatusListenerMock);
1448        executeAndValidateInitializationSequence();
1449        executeAndValidateStartupSequence();
1450
1451        // try API
1452        Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
1453
1454        // verify results
1455        Set<Integer> correctResults = new HashSet<>();
1456        correctResults.add(IfaceType.AP);
1457        correctResults.add(IfaceType.STA);
1458        correctResults.add(IfaceType.P2P);
1459        correctResults.add(IfaceType.NAN);
1460
1461        assertEquals(correctResults, results);
1462    }
1463
1464    //////////////////////////////////////////////////////////////////////////////////////
1465    // TestChipV3 Specific Tests
1466    //////////////////////////////////////////////////////////////////////////////////////
1467
1468    /**
1469     * Validate a flow sequence for test chip 3:
1470     * - create STA
1471     * - create P2P
1472     * - request NAN: failure
1473     * - create AP: should tear down P2P first
1474     * - create STA: will get refused
1475     * - create AP: will get refused
1476     * - request P2P: failure
1477     * - tear down AP
1478     * - create STA
1479     * - create STA: will get refused
1480     * - create NAN: should tear down last created STA
1481     * - create STA: will get refused
1482     */
1483    @Test
1484    public void testInterfaceCreationFlowTestChipV3() throws Exception {
1485        TestChipV3 chipMock = new TestChipV3();
1486        chipMock.initialize();
1487        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1488                mManagerStatusListenerMock);
1489        executeAndValidateInitializationSequence();
1490        executeAndValidateStartupSequence();
1491
1492        InterfaceDestroyedListener staDestroyedListener = mock(
1493                InterfaceDestroyedListener.class);
1494        InterfaceDestroyedListener staDestroyedListener2 = mock(
1495                InterfaceDestroyedListener.class);
1496        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
1497                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1498
1499        InterfaceDestroyedListener apDestroyedListener = mock(
1500                InterfaceDestroyedListener.class);
1501        HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
1502                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1503
1504        InterfaceDestroyedListener p2pDestroyedListener = mock(
1505                InterfaceDestroyedListener.class);
1506        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
1507                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1508
1509        InterfaceDestroyedListener nanDestroyedListener = mock(
1510                InterfaceDestroyedListener.class);
1511        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
1512                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1513
1514        InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
1515                nanAvailListener);
1516
1517        // register listeners for interface availability
1518        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
1519                mHandler);
1520        mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
1521        mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
1522                mHandler);
1523        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
1524                mHandler);
1525        mTestLooper.dispatchAll();
1526
1527        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1528        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1529        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1530        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1531
1532        // create STA
1533        when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
1534        IWifiIface staIface = validateInterfaceSequence(chipMock,
1535                false, // chipModeValid
1536                -1000, // chipModeId (only used if chipModeValid is true)
1537                IfaceType.STA, // ifaceTypeToCreate
1538                "wlan0", // ifaceName
1539                TestChipV3.CHIP_MODE_ID, // finalChipMode
1540                false, // high priority
1541                null, // tearDownList
1542                staDestroyedListener, // destroyedListener
1543                null // availableListener (already registered)
1544        );
1545        collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
1546
1547        // create P2P
1548        IWifiIface p2pIface = validateInterfaceSequence(chipMock,
1549                true, // chipModeValid
1550                TestChipV3.CHIP_MODE_ID, // chipModeId
1551                IfaceType.P2P, // ifaceTypeToCreate
1552                "p2p0", // ifaceName
1553                TestChipV3.CHIP_MODE_ID, // finalChipMode
1554                false, // high priority (but irrelevant)
1555                null, // tearDownList
1556                p2pDestroyedListener, // destroyedListener
1557                null // availableListener (already registered)
1558        );
1559        collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
1560
1561        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1562        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
1563        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1564
1565        // request NAN: should fail
1566        IWifiIface nanIface = mDut.createNanIface(null, null);
1567        collector.checkThat("NAN should not be created", nanIface, IsNull.nullValue());
1568
1569        // create AP: will destroy P2P
1570        IWifiIface apIface = validateInterfaceSequence(chipMock,
1571                true, // chipModeValid
1572                TestChipV3.CHIP_MODE_ID, // chipModeId
1573                IfaceType.AP, // ifaceTypeToCreate
1574                "wlan1", // ifaceName
1575                TestChipV3.CHIP_MODE_ID, // finalChipMode
1576                false, // high priority (but irrelevant)
1577                null, // tearDownList
1578                apDestroyedListener, // destroyedListener
1579                null, // availableListener (already registered)
1580                new InterfaceDestroyedListenerWithIfaceName("p2p0", p2pDestroyedListener)
1581        );
1582        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
1583        verify(chipMock.chip).removeP2pIface("p2p0");
1584
1585        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
1586
1587        // request STA2: should fail
1588        IWifiIface staIface2 = mDut.createStaIface(false, null, null);
1589        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1590
1591        // request AP2: should fail
1592        IWifiIface apIface2 = mDut.createApIface(null, null);
1593        collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
1594
1595        // request P2P: should fail
1596        p2pIface = mDut.createP2pIface(null, null);
1597        collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
1598
1599        // tear down AP
1600        mDut.removeIface(apIface);
1601        mTestLooper.dispatchAll();
1602
1603        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1604        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1605        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1606        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1607        verify(chipMock.chip).removeApIface("wlan1");
1608        verify(apDestroyedListener).onDestroyed(getName(apIface));
1609
1610        // create STA2: using a later clock
1611        when(mClock.getUptimeSinceBootMillis()).thenReturn(20L);
1612        staIface2 = validateInterfaceSequence(chipMock,
1613                true, // chipModeValid
1614                TestChipV3.CHIP_MODE_ID, // chipModeId
1615                IfaceType.STA, // ifaceTypeToCreate
1616                "wlan1", // ifaceName
1617                TestChipV3.CHIP_MODE_ID, // finalChipMode
1618                false, // high priority
1619                null, // tearDownList
1620                staDestroyedListener2, // destroyedListener
1621                null // availableListener (already registered)
1622        );
1623        collector.checkThat("STA 2 interface wasn't created", staIface2, IsNull.notNullValue());
1624
1625        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1626
1627        // request STA3: should fail
1628        IWifiIface staIface3 = mDut.createStaIface(false, null, null);
1629        collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
1630
1631        // create NAN: should destroy the last created STA (STA2)
1632        nanIface = validateInterfaceSequence(chipMock,
1633                true, // chipModeValid
1634                TestChipV3.CHIP_MODE_ID, // chipModeId
1635                IfaceType.NAN, // ifaceTypeToCreate
1636                "wlan0", // ifaceName
1637                TestChipV3.CHIP_MODE_ID, // finalChipMode
1638                false, // high priority (but irrelevant)
1639                null, // tearDownList
1640                nanDestroyedListener, // destroyedListener
1641                null, // availableListener (already registered)
1642                new InterfaceDestroyedListenerWithIfaceName(
1643                        getName(staIface2), staDestroyedListener2)
1644        );
1645        collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
1646
1647        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1648        verify(chipMock.chip).removeStaIface("wlan1");
1649        verify(staDestroyedListener2).onDestroyed(getName(staIface2));
1650
1651        // request STA2: should fail
1652        staIface2 = mDut.createStaIface(false, null, null);
1653        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1654
1655        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
1656                staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
1657                nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
1658                nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
1659                nanAvailListener);
1660    }
1661
1662    /**
1663     * Validate P2P and NAN interactions. Expect:
1664     * - STA created
1665     * - NAN created
1666     * - When P2P requested:
1667     *   - NAN torn down
1668     *   - P2P created
1669     * - NAN creation refused
1670     * - When P2P destroyed:
1671     *   - get nan available listener
1672     *   - Can create NAN when requested
1673     */
1674    @Test
1675    public void testP2pAndNanInteractionsTestChipV3() throws Exception {
1676        runP2pAndNanExclusiveInteractionsTestChip(new TestChipV3(), TestChipV3.CHIP_MODE_ID);
1677    }
1678
1679    /**
1680     * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
1681     */
1682    @Test
1683    public void testGetSupportedIfaceTypesAllTestChipV3() throws Exception {
1684        TestChipV3 chipMock = new TestChipV3();
1685        chipMock.initialize();
1686        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1687                mManagerStatusListenerMock);
1688        executeAndValidateInitializationSequence();
1689        executeAndValidateStartupSequence();
1690
1691        // try API
1692        Set<Integer> results = mDut.getSupportedIfaceTypes();
1693
1694        // verify results
1695        Set<Integer> correctResults = new HashSet<>();
1696        correctResults.add(IfaceType.AP);
1697        correctResults.add(IfaceType.STA);
1698        correctResults.add(IfaceType.P2P);
1699        correctResults.add(IfaceType.NAN);
1700
1701        assertEquals(correctResults, results);
1702    }
1703
1704    /**
1705     * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
1706     */
1707    @Test
1708    public void testGetSupportedIfaceTypesOneChipTestChipV3() throws Exception {
1709        TestChipV3 chipMock = new TestChipV3();
1710        chipMock.initialize();
1711        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1712                mManagerStatusListenerMock);
1713        executeAndValidateInitializationSequence();
1714        executeAndValidateStartupSequence();
1715
1716        // try API
1717        Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
1718
1719        // verify results
1720        Set<Integer> correctResults = new HashSet<>();
1721        correctResults.add(IfaceType.AP);
1722        correctResults.add(IfaceType.STA);
1723        correctResults.add(IfaceType.P2P);
1724        correctResults.add(IfaceType.NAN);
1725
1726        assertEquals(correctResults, results);
1727    }
1728
1729    //////////////////////////////////////////////////////////////////////////////////////
1730    // TestChipV4 Specific Tests
1731    //////////////////////////////////////////////////////////////////////////////////////
1732
1733    /**
1734     * Validate a flow sequence for test chip 4:
1735     * - create STA
1736     * - create P2P
1737     * - request NAN: failure
1738     * - create AP: should tear down P2P first
1739     * - create STA: will get refused
1740     * - create AP: will get refused
1741     * - request P2P: failure
1742     * - tear down AP
1743     * - create STA: will get refused
1744     * - create NAN
1745     * - create STA: will get refused
1746     */
1747    @Test
1748    public void testInterfaceCreationFlowTestChipV4() throws Exception {
1749        TestChipV4 chipMock = new TestChipV4();
1750        chipMock.initialize();
1751        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1752                mManagerStatusListenerMock);
1753        executeAndValidateInitializationSequence();
1754        executeAndValidateStartupSequence();
1755
1756        InterfaceDestroyedListener staDestroyedListener = mock(
1757                InterfaceDestroyedListener.class);
1758        InterfaceDestroyedListener staDestroyedListener2 = mock(
1759                InterfaceDestroyedListener.class);
1760        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
1761                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1762
1763        InterfaceDestroyedListener apDestroyedListener = mock(
1764                InterfaceDestroyedListener.class);
1765        HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
1766                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1767
1768        InterfaceDestroyedListener p2pDestroyedListener = mock(
1769                InterfaceDestroyedListener.class);
1770        HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
1771                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1772
1773        InterfaceDestroyedListener nanDestroyedListener = mock(
1774                InterfaceDestroyedListener.class);
1775        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
1776                HalDeviceManager.InterfaceAvailableForRequestListener.class);
1777
1778        InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
1779                nanAvailListener);
1780
1781        // register listeners for interface availability
1782        mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
1783                mHandler);
1784        mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
1785        mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
1786                mHandler);
1787        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
1788                mHandler);
1789        mTestLooper.dispatchAll();
1790
1791        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1792        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1793        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1794        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1795
1796        // create STA
1797        when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
1798        IWifiIface staIface = validateInterfaceSequence(chipMock,
1799                false, // chipModeValid
1800                -1000, // chipModeId (only used if chipModeValid is true)
1801                IfaceType.STA, // ifaceTypeToCreate
1802                "wlan0", // ifaceName
1803                TestChipV4.CHIP_MODE_ID, // finalChipMode
1804                false, // high priority
1805                null, // tearDownList
1806                staDestroyedListener, // destroyedListener
1807                null // availableListener (already registered)
1808        );
1809        collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
1810        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
1811
1812        // create P2P
1813        IWifiIface p2pIface = validateInterfaceSequence(chipMock,
1814                true, // chipModeValid
1815                TestChipV4.CHIP_MODE_ID, // chipModeId
1816                IfaceType.P2P, // ifaceTypeToCreate
1817                "p2p0", // ifaceName
1818                TestChipV4.CHIP_MODE_ID, // finalChipMode
1819                false, // high priority (but irrelevant)
1820                null, // tearDownList
1821                p2pDestroyedListener, // destroyedListener
1822                null // availableListener (already registered)
1823        );
1824        collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
1825
1826        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
1827        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1828
1829        // request NAN: should fail
1830        IWifiIface nanIface = mDut.createNanIface(null, null);
1831        collector.checkThat("NAN should not be created", nanIface, IsNull.nullValue());
1832
1833        // create AP: will destroy P2P
1834        IWifiIface apIface = validateInterfaceSequence(chipMock,
1835                true, // chipModeValid
1836                TestChipV4.CHIP_MODE_ID, // chipModeId
1837                IfaceType.AP, // ifaceTypeToCreate
1838                "wlan1", // ifaceName
1839                TestChipV4.CHIP_MODE_ID, // finalChipMode
1840                false, // high priority (but irrelevant)
1841                null, // tearDownList
1842                apDestroyedListener, // destroyedListener
1843                null, // availableListener (already registered)
1844                new InterfaceDestroyedListenerWithIfaceName("p2p0", p2pDestroyedListener)
1845        );
1846        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
1847        verify(chipMock.chip).removeP2pIface("p2p0");
1848
1849        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
1850
1851        // request STA2: should fail
1852        IWifiIface staIface2 = mDut.createStaIface(false, null, null);
1853        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1854
1855        // request AP2: should fail
1856        IWifiIface apIface2 = mDut.createApIface(null, null);
1857        collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
1858
1859        // request P2P: should fail
1860        p2pIface = mDut.createP2pIface(null, null);
1861        collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
1862
1863        // tear down AP
1864        mDut.removeIface(apIface);
1865        mTestLooper.dispatchAll();
1866
1867        inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
1868        inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
1869        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
1870        verify(chipMock.chip).removeApIface("wlan1");
1871        verify(apDestroyedListener).onDestroyed(getName(apIface));
1872
1873        // request STA2: should fail
1874        staIface2 = mDut.createStaIface(false, null, null);
1875        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1876
1877        // create NAN
1878        nanIface = validateInterfaceSequence(chipMock,
1879                true, // chipModeValid
1880                TestChipV4.CHIP_MODE_ID, // chipModeId
1881                IfaceType.NAN, // ifaceTypeToCreate
1882                "wlan0", // ifaceName
1883                TestChipV4.CHIP_MODE_ID, // finalChipMode
1884                false, // high priority (but irrelevant)
1885                null, // tearDownList
1886                nanDestroyedListener, // destroyedListener
1887                null // availableListener (already registered)
1888        );
1889        collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
1890
1891        inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
1892
1893        // request STA2: should fail
1894        staIface2 = mDut.createStaIface(false, null, null);
1895        collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
1896
1897        // tear down STA
1898        mDut.removeIface(staIface);
1899        mTestLooper.dispatchAll();
1900
1901        inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
1902        verify(chipMock.chip).removeStaIface("wlan0");
1903        verify(staDestroyedListener).onDestroyed(getName(staIface));
1904
1905        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
1906                staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
1907                nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
1908                nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
1909                nanAvailListener);
1910    }
1911
1912    /**
1913     * Validate P2P and NAN interactions. Expect:
1914     * - STA created
1915     * - NAN created
1916     * - When P2P requested:
1917     *   - NAN torn down
1918     *   - P2P created
1919     * - NAN creation refused
1920     * - When P2P destroyed:
1921     *   - get nan available listener
1922     *   - Can create NAN when requested
1923     */
1924    @Test
1925    public void testP2pAndNanInteractionsTestChipV4() throws Exception {
1926        runP2pAndNanExclusiveInteractionsTestChip(new TestChipV4(), TestChipV4.CHIP_MODE_ID);
1927    }
1928
1929    /**
1930     * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
1931     */
1932    @Test
1933    public void testGetSupportedIfaceTypesAllTestChipV4() throws Exception {
1934        TestChipV4 chipMock = new TestChipV4();
1935        chipMock.initialize();
1936        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1937                mManagerStatusListenerMock);
1938        executeAndValidateInitializationSequence();
1939        executeAndValidateStartupSequence();
1940
1941        // try API
1942        Set<Integer> results = mDut.getSupportedIfaceTypes();
1943
1944        // verify results
1945        Set<Integer> correctResults = new HashSet<>();
1946        correctResults.add(IfaceType.AP);
1947        correctResults.add(IfaceType.STA);
1948        correctResults.add(IfaceType.P2P);
1949        correctResults.add(IfaceType.NAN);
1950
1951        assertEquals(correctResults, results);
1952    }
1953
1954    /**
1955     * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
1956     */
1957    @Test
1958    public void testGetSupportedIfaceTypesOneChipTestChipV4() throws Exception {
1959        TestChipV4 chipMock = new TestChipV4();
1960        chipMock.initialize();
1961        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1962                mManagerStatusListenerMock);
1963        executeAndValidateInitializationSequence();
1964        executeAndValidateStartupSequence();
1965
1966        // try API
1967        Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
1968
1969        // verify results
1970        Set<Integer> correctResults = new HashSet<>();
1971        correctResults.add(IfaceType.AP);
1972        correctResults.add(IfaceType.STA);
1973        correctResults.add(IfaceType.P2P);
1974        correctResults.add(IfaceType.NAN);
1975
1976        assertEquals(correctResults, results);
1977    }
1978
1979    ///////////////////////////////////////////////////////////////////////////////////////
1980    // Tests targeting low priority STA creation
1981    ///////////////////////////////////////////////////////////////////////////////////////
1982
1983    /**
1984     * Validate low priority STA management on Test Chip V1 (which has single STA capability).
1985     * Procedure:
1986     * - Create STA
1987     * - Create STA(low priority): expect failure
1988     * - Create AP: expect STA to be deleted
1989     * - Create STA(low priority): expect failure
1990     * - Delete AP
1991     * - Create STA(low priority): success!
1992     * - Create STA: expect STA(low priority) to be deleted
1993     */
1994    @Test
1995    public void testLowPriorityStaTestChipV1() throws Exception {
1996        TestChipV1 chipMock = new TestChipV1();
1997        chipMock.initialize();
1998        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1999                mManagerStatusListenerMock);
2000        executeAndValidateInitializationSequence();
2001        executeAndValidateStartupSequence();
2002
2003        InterfaceDestroyedListener staDestroyedListener = mock(
2004                InterfaceDestroyedListener.class);
2005        InterfaceDestroyedListener staLpDestroyedListener = mock(
2006                InterfaceDestroyedListener.class);
2007        InterfaceDestroyedListener apDestroyedListener = mock(
2008                InterfaceDestroyedListener.class);
2009
2010        // create STA
2011        IWifiIface staIface = validateInterfaceSequence(chipMock,
2012                false, // chipModeValid
2013                -1000, // chipModeId (only used if chipModeValid is true)
2014                IfaceType.STA, // ifaceTypeToCreate
2015                "wlan0", // ifaceName
2016                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
2017                false, // high priority
2018                null, // tearDownList
2019                staDestroyedListener, // destroyedListener
2020                null // availableListener (already registered)
2021        );
2022        collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
2023
2024        // request STA(low priority): should fail
2025        IWifiIface staLowIface = mDut.createStaIface(true, null, null);
2026        collector.checkThat("STA(low priority) should not be created", staLowIface,
2027                IsNull.nullValue());
2028
2029        // create AP: will destroy STA
2030        IWifiIface apIface = validateInterfaceSequence(chipMock,
2031                true, // chipModeValid
2032                TestChipV1.STA_CHIP_MODE_ID, // chipModeId
2033                IfaceType.AP, // ifaceTypeToCreate
2034                "ap0", // ifaceName
2035                TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
2036                false, // high priority (but irrelevant)
2037                null, // tearDownList
2038                apDestroyedListener, // destroyedListener
2039                null, // availableListener (already registered)
2040                new InterfaceDestroyedListenerWithIfaceName("wlan0", staDestroyedListener)
2041        );
2042        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
2043
2044        // request STA(low priority): should fail
2045        staLowIface = mDut.createStaIface(true, null, null);
2046        collector.checkThat("STA(low priority) should not be created", staLowIface,
2047                IsNull.nullValue());
2048
2049        // tear down AP
2050        mDut.removeIface(apIface);
2051        mTestLooper.dispatchAll();
2052        verify(chipMock.chip).removeApIface("ap0");
2053        verify(apDestroyedListener).onDestroyed(getName(apIface));
2054
2055        // create STA(low priority)
2056        staLowIface = validateInterfaceSequence(chipMock,
2057                true, // chipModeValid
2058                TestChipV1.AP_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
2059                IfaceType.STA, // ifaceTypeToCreate
2060                "wlan1", // ifaceName
2061                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
2062                true, // low priority
2063                null, // tearDownList
2064                staLpDestroyedListener, // destroyedListener
2065                null // availableListener (already registered)
2066        );
2067        collector.checkThat("STA(low priority) interface wasn't created", staIface,
2068                IsNull.notNullValue());
2069
2070        // create STA: should destroy the low priority STA
2071        staIface = validateInterfaceSequence(chipMock,
2072                true, // chipModeValid
2073                TestChipV1.STA_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
2074                IfaceType.STA, // ifaceTypeToCreate
2075                "wlan0", // ifaceName
2076                TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
2077                false, // high priority
2078                null, // tearDownList
2079                staDestroyedListener, // destroyedListener
2080                null, // availableListener (already registered)
2081                new InterfaceDestroyedListenerWithIfaceName("wlan1", staLpDestroyedListener)
2082        );
2083        collector.checkThat("STA interface wasn't created", staIface,
2084                IsNull.notNullValue());
2085
2086        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
2087                apDestroyedListener, staLpDestroyedListener);
2088    }
2089
2090    /**
2091     * Validate low priority STA management on Test Chip V4 (which has single STA+AP capability).
2092     * Procedure:
2093     * - Create STA
2094     * - Create STA(low priority): expect failure
2095     * - Create AP
2096     * - Create STA: expect failure
2097     * - Destroy STA
2098     * - Create STA(low priority): success!
2099     * - Create STA: expect STA(low priority) to be deleted
2100     */
2101    @Test
2102    public void testLowPriorityStaTestChipV4() throws Exception {
2103        TestChipV4 chipMock = new TestChipV4();
2104        chipMock.initialize();
2105        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
2106                mManagerStatusListenerMock);
2107        executeAndValidateInitializationSequence();
2108        executeAndValidateStartupSequence();
2109
2110        InterfaceDestroyedListener staDestroyedListener = mock(
2111                InterfaceDestroyedListener.class);
2112        InterfaceDestroyedListener staLpDestroyedListener = mock(
2113                InterfaceDestroyedListener.class);
2114        InterfaceDestroyedListener apDestroyedListener = mock(
2115                InterfaceDestroyedListener.class);
2116
2117        // create STA
2118        IWifiIface staIface = validateInterfaceSequence(chipMock,
2119                false, // chipModeValid
2120                -1000, // chipModeId (only used if chipModeValid is true)
2121                IfaceType.STA, // ifaceTypeToCreate
2122                "wlan0", // ifaceName
2123                TestChipV4.CHIP_MODE_ID, // finalChipMode
2124                false, // high priority
2125                null, // tearDownList
2126                staDestroyedListener, // destroyedListener
2127                null // availableListener (already registered)
2128        );
2129        collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
2130
2131        // request STA(low priority): should fail
2132        IWifiIface staLowIface = mDut.createStaIface(true, null, null);
2133        collector.checkThat("STA(low priority) should not be created", staLowIface,
2134                IsNull.nullValue());
2135
2136        // create AP
2137        IWifiIface apIface = validateInterfaceSequence(chipMock,
2138                true, // chipModeValid
2139                TestChipV4.CHIP_MODE_ID, // chipModeId
2140                IfaceType.AP, // ifaceTypeToCreate
2141                "ap0", // ifaceName
2142                TestChipV4.CHIP_MODE_ID, // finalChipMode
2143                false, // high priority (but irrelevant)
2144                null, // tearDownList
2145                apDestroyedListener, // destroyedListener
2146                null // availableListener (already registered)
2147        );
2148        collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
2149
2150        // request STA2: should fail
2151        IWifiIface sta2Iface = mDut.createStaIface(true, null, null);
2152        collector.checkThat("STA2 should not be created", sta2Iface,
2153                IsNull.nullValue());
2154
2155        // tear down STA
2156        mDut.removeIface(staIface);
2157        mTestLooper.dispatchAll();
2158        verify(chipMock.chip).removeStaIface("wlan0");
2159        verify(staDestroyedListener).onDestroyed(getName(staIface));
2160
2161        // create STA(low priority)
2162        staLowIface = validateInterfaceSequence(chipMock,
2163                true, // chipModeValid
2164                TestChipV4.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
2165                IfaceType.STA, // ifaceTypeToCreate
2166                "wlan1", // ifaceName
2167                TestChipV4.CHIP_MODE_ID, // finalChipMode
2168                true, // low priority
2169                null, // tearDownList
2170                staLpDestroyedListener, // destroyedListener
2171                null // availableListener (already registered)
2172        );
2173        collector.checkThat("STA(low priority) interface wasn't created", staIface,
2174                IsNull.notNullValue());
2175
2176        // create STA: should destroy the low priority STA
2177        staIface = validateInterfaceSequence(chipMock,
2178                true, // chipModeValid
2179                TestChipV4.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
2180                IfaceType.STA, // ifaceTypeToCreate
2181                "wlan0", // ifaceName
2182                TestChipV4.CHIP_MODE_ID, // finalChipMode
2183                false, // high priority
2184                null, // tearDownList
2185                staDestroyedListener, // destroyedListener
2186                null, // availableListener (already registered)
2187                new InterfaceDestroyedListenerWithIfaceName("wlan1", staLpDestroyedListener)
2188        );
2189        collector.checkThat("STA interface wasn't created", staIface,
2190                IsNull.notNullValue());
2191
2192        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
2193                apDestroyedListener, staLpDestroyedListener);
2194    }
2195
2196    ///////////////////////////////////////////////////////////////////////////////////////
2197    // utilities
2198    ///////////////////////////////////////////////////////////////////////////////////////
2199    private void dumpDut(String prefix) {
2200        StringWriter sw = new StringWriter();
2201        mDut.dump(null, new PrintWriter(sw), null);
2202        Log.e("HalDeviceManager", prefix + sw.toString());
2203    }
2204
2205    private void executeAndValidateInitializationSequence() throws Exception {
2206        executeAndValidateInitializationSequence(true);
2207    }
2208
2209    private void executeAndValidateInitializationSequence(boolean isSupported) throws Exception {
2210        // act:
2211        mDut.initialize();
2212
2213        // verify: service manager initialization sequence
2214        mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
2215                anyLong());
2216        mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
2217                eq(""), mServiceNotificationCaptor.capture());
2218
2219        // The service should already be up at this point.
2220        mInOrder.verify(mServiceManagerMock).getTransport(eq(IWifi.kInterfaceName),
2221                eq(HalDeviceManager.HAL_INSTANCE_NAME));
2222
2223        // verify: wifi initialization sequence if vendor HAL is supported.
2224        if (isSupported) {
2225            mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
2226            mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
2227            // verify: onStop called as a part of initialize.
2228            mInOrder.verify(mWifiMock).stop();
2229            collector.checkThat("isReady is true", mDut.isReady(), equalTo(true));
2230        } else {
2231            collector.checkThat("isReady is false", mDut.isReady(), equalTo(false));
2232        }
2233    }
2234
2235    private void executeAndValidateStartupSequence()throws Exception {
2236        executeAndValidateStartupSequence(1, true);
2237    }
2238
2239    private void executeAndValidateStartupSequence(int numAttempts, boolean success)
2240            throws Exception {
2241        // act: register listener & start Wi-Fi
2242        mDut.registerStatusListener(mManagerStatusListenerMock, mHandler);
2243        collector.checkThat(mDut.start(), equalTo(success));
2244
2245        // verify
2246        mInOrder.verify(mWifiMock, times(numAttempts)).start();
2247
2248        if (success) {
2249            // act: trigger onStart callback of IWifiEventCallback
2250            mWifiEventCallbackCaptor.getValue().onStart();
2251            mTestLooper.dispatchAll();
2252
2253            // verify: onStart called on registered listener
2254            mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
2255        }
2256    }
2257
2258    private void runCreateSingleXxxInterfaceNoInitMode(ChipMockBase chipMock, int ifaceTypeToCreate,
2259            String ifaceName, int finalChipMode, boolean multipleIfaceSupport) throws Exception {
2260        chipMock.initialize();
2261        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
2262                mManagerStatusListenerMock);
2263        executeAndValidateInitializationSequence();
2264        executeAndValidateStartupSequence();
2265
2266        InterfaceDestroyedListener idl = mock(
2267                InterfaceDestroyedListener.class);
2268        HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
2269                HalDeviceManager.InterfaceAvailableForRequestListener.class);
2270
2271        InOrder availInOrder = inOrder(iafrl);
2272
2273        IWifiIface iface = validateInterfaceSequence(chipMock,
2274                false, // chipModeValid
2275                -1000, // chipModeId (only used if chipModeValid is true)
2276                ifaceTypeToCreate,
2277                ifaceName,
2278                finalChipMode,
2279                false, // high priority
2280                null, // tearDownList
2281                idl, // destroyedListener
2282                iafrl // availableListener
2283        );
2284        collector.checkThat("allocated interface", iface, IsNull.notNullValue());
2285        availInOrder.verify(iafrl).onAvailabilityChanged(multipleIfaceSupport);
2286
2287        // act: remove interface
2288        mDut.removeIface(iface);
2289        mTestLooper.dispatchAll();
2290
2291        // verify: callback triggered
2292        switch (ifaceTypeToCreate) {
2293            case IfaceType.STA:
2294                mInOrder.verify(chipMock.chip).removeStaIface(ifaceName);
2295                break;
2296            case IfaceType.AP:
2297                mInOrder.verify(chipMock.chip).removeApIface(ifaceName);
2298                break;
2299            case IfaceType.P2P:
2300                mInOrder.verify(chipMock.chip).removeP2pIface(ifaceName);
2301                break;
2302            case IfaceType.NAN:
2303                mInOrder.verify(chipMock.chip).removeNanIface(ifaceName);
2304                break;
2305        }
2306
2307        verify(idl).onDestroyed(ifaceName);
2308        if (!multipleIfaceSupport) {
2309            availInOrder.verify(iafrl).onAvailabilityChanged(true);
2310        }
2311
2312        verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
2313    }
2314
2315    /**
2316     * Validate P2P and NAN interactions. Expect:
2317     * - STA created
2318     * - NAN created
2319     * - When P2P requested:
2320     *   - NAN torn down
2321     *   - P2P created
2322     * - NAN creation refused
2323     * - When P2P destroyed:
2324     *   - get nan available listener
2325     *   - Can create NAN when requested
2326     *
2327     * Relevant for any chip which supports STA + NAN || P2P (or a richer combination - but bottom
2328     * line of NAN and P2P being exclusive).
2329     */
2330    public void runP2pAndNanExclusiveInteractionsTestChip(ChipMockBase chipMock,
2331            int onlyChipMode) throws Exception {
2332        chipMock.initialize();
2333        mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
2334                mManagerStatusListenerMock);
2335        executeAndValidateInitializationSequence();
2336        executeAndValidateStartupSequence();
2337
2338        InterfaceDestroyedListener staDestroyedListener = mock(
2339                InterfaceDestroyedListener.class);
2340        HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
2341                HalDeviceManager.InterfaceAvailableForRequestListener.class);
2342
2343        InterfaceDestroyedListener nanDestroyedListener = mock(
2344                InterfaceDestroyedListener.class);
2345        HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
2346                HalDeviceManager.InterfaceAvailableForRequestListener.class);
2347
2348        InterfaceDestroyedListener p2pDestroyedListener = mock(
2349                InterfaceDestroyedListener.class);
2350
2351        InOrder availInOrder = inOrder(staAvailListener, nanAvailListener);
2352
2353        // Request STA
2354        IWifiIface staIface = validateInterfaceSequence(chipMock,
2355                false, // chipModeValid
2356                -1000, // chipModeId (only used if chipModeValid is true)
2357                IfaceType.STA, // ifaceTypeToCreate
2358                "wlan0", // ifaceName
2359                onlyChipMode, // finalChipMode
2360                false, // high priority
2361                null, // tearDownList
2362                staDestroyedListener, // destroyedListener
2363                staAvailListener // availableListener
2364        );
2365        availInOrder.verify(staAvailListener).onAvailabilityChanged(
2366                chipMock.chipMockId == CHIP_MOCK_V2 || chipMock.chipMockId == CHIP_MOCK_V3);
2367
2368        // Request NAN
2369        IWifiIface nanIface = validateInterfaceSequence(chipMock,
2370                true, // chipModeValid
2371                onlyChipMode, // chipModeId
2372                IfaceType.NAN, // ifaceTypeToCreate
2373                "wlan0", // ifaceName
2374                onlyChipMode, // finalChipMode
2375                false, // high priority (but irrelevant)
2376                null, // tearDownList
2377                nanDestroyedListener, // destroyedListener
2378                nanAvailListener // availableListener
2379        );
2380        if (chipMock.chipMockId == CHIP_MOCK_V3) {
2381            availInOrder.verify(staAvailListener).onAvailabilityChanged(false);
2382        }
2383        availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
2384
2385        // Request P2P
2386        IWifiIface p2pIface = validateInterfaceSequence(chipMock,
2387                true, // chipModeValid
2388                onlyChipMode, // chipModeId
2389                IfaceType.P2P, // ifaceTypeToCreate
2390                "p2p0", // ifaceName
2391                onlyChipMode, // finalChipMode
2392                false, // high priority (but irrelevant)
2393                new IWifiIface[]{nanIface}, // tearDownList
2394                p2pDestroyedListener, // destroyedListener
2395                null, // availableListener
2396                // destroyedInterfacesDestroyedListeners...
2397                new InterfaceDestroyedListenerWithIfaceName(
2398                        getName(nanIface), nanDestroyedListener)
2399        );
2400
2401        // Request NAN: expect failure
2402        nanIface = mDut.createNanIface(nanDestroyedListener, mHandler);
2403        mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
2404                mHandler);
2405        collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
2406
2407        // Destroy P2P interface
2408        boolean status = mDut.removeIface(p2pIface);
2409        mInOrder.verify(chipMock.chip).removeP2pIface("p2p0");
2410        collector.checkThat("P2P removal success", status, equalTo(true));
2411
2412        mTestLooper.dispatchAll();
2413        verify(p2pDestroyedListener).onDestroyed(getName(p2pIface));
2414        if (chipMock.chipMockId == CHIP_MOCK_V3) {
2415            availInOrder.verify(staAvailListener).onAvailabilityChanged(true);
2416        }
2417        availInOrder.verify(nanAvailListener).onAvailabilityChanged(true);
2418
2419        // Request NAN: expect success now
2420        nanIface = validateInterfaceSequence(chipMock,
2421                true, // chipModeValid
2422                onlyChipMode, // chipModeId
2423                IfaceType.NAN, // ifaceTypeToCreate
2424                "wlan0", // ifaceName
2425                onlyChipMode, // finalChipMode
2426                false, // high priority (but irrelevant)
2427                null, // tearDownList
2428                nanDestroyedListener, // destroyedListener
2429                nanAvailListener // availableListener
2430        );
2431        if (chipMock.chipMockId == CHIP_MOCK_V3) {
2432            availInOrder.verify(staAvailListener).onAvailabilityChanged(false);
2433        }
2434        availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
2435
2436        verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
2437                nanDestroyedListener, nanAvailListener, p2pDestroyedListener);
2438    }
2439
2440    private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
2441            boolean chipModeValid, int chipModeId,
2442            int ifaceTypeToCreate, String ifaceName, int finalChipMode, boolean lowPriority,
2443            IWifiIface[] tearDownList,
2444            InterfaceDestroyedListener destroyedListener,
2445            HalDeviceManager.InterfaceAvailableForRequestListener availableListener,
2446            InterfaceDestroyedListenerWithIfaceName...destroyedInterfacesDestroyedListeners)
2447            throws Exception {
2448        // configure chip mode response
2449        chipMock.chipModeValid = chipModeValid;
2450        chipMock.chipModeId = chipModeId;
2451
2452        IWifiIface iface = null;
2453
2454        // configure: interface to be created
2455        // act: request the interface
2456        switch (ifaceTypeToCreate) {
2457            case IfaceType.STA:
2458                iface = mock(IWifiStaIface.class);
2459                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
2460                        any(IWifiIface.getNameCallback.class));
2461                doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
2462                        any(IWifiIface.getTypeCallback.class));
2463                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
2464                        chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
2465
2466                mDut.createStaIface(lowPriority, destroyedListener, mHandler);
2467                break;
2468            case IfaceType.AP:
2469                iface = mock(IWifiApIface.class);
2470                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
2471                        any(IWifiIface.getNameCallback.class));
2472                doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
2473                        any(IWifiIface.getTypeCallback.class));
2474                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
2475                        chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
2476
2477                mDut.createApIface(destroyedListener, mHandler);
2478                break;
2479            case IfaceType.P2P:
2480                iface = mock(IWifiP2pIface.class);
2481                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
2482                        any(IWifiIface.getNameCallback.class));
2483                doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
2484                        any(IWifiIface.getTypeCallback.class));
2485                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
2486                        chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
2487
2488                mDut.createP2pIface(destroyedListener, mHandler);
2489                break;
2490            case IfaceType.NAN:
2491                iface = mock(IWifiNanIface.class);
2492                doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
2493                        any(IWifiIface.getNameCallback.class));
2494                doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
2495                        any(IWifiIface.getTypeCallback.class));
2496                doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
2497                        chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
2498
2499                mDut.createNanIface(destroyedListener, mHandler);
2500                break;
2501        }
2502        if (availableListener != null) {
2503            mDut.registerInterfaceAvailableForRequestListener(ifaceTypeToCreate, availableListener,
2504                    mHandler);
2505        }
2506
2507        // validate: optional tear down of interfaces
2508        if (tearDownList != null) {
2509            for (IWifiIface tearDownIface: tearDownList) {
2510                switch (getType(tearDownIface)) {
2511                    case IfaceType.STA:
2512                        mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
2513                        break;
2514                    case IfaceType.AP:
2515                        mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
2516                        break;
2517                    case IfaceType.P2P:
2518                        mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
2519                        break;
2520                    case IfaceType.NAN:
2521                        mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
2522                        break;
2523                }
2524            }
2525        }
2526
2527        // validate: optional switch to the requested mode
2528        if (!chipModeValid || chipModeId != finalChipMode) {
2529            mInOrder.verify(chipMock.chip).configureChip(finalChipMode);
2530        } else {
2531            mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt());
2532        }
2533
2534        // validate: create interface
2535        switch (ifaceTypeToCreate) {
2536            case IfaceType.STA:
2537                mInOrder.verify(chipMock.chip).createStaIface(
2538                        any(IWifiChip.createStaIfaceCallback.class));
2539                break;
2540            case IfaceType.AP:
2541                mInOrder.verify(chipMock.chip).createApIface(
2542                        any(IWifiChip.createApIfaceCallback.class));
2543                break;
2544            case IfaceType.P2P:
2545                mInOrder.verify(chipMock.chip).createP2pIface(
2546                        any(IWifiChip.createP2pIfaceCallback.class));
2547                break;
2548            case IfaceType.NAN:
2549                mInOrder.verify(chipMock.chip).createNanIface(
2550                        any(IWifiChip.createNanIfaceCallback.class));
2551                break;
2552        }
2553
2554        // verify: callbacks on deleted interfaces
2555        mTestLooper.dispatchAll();
2556        for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) {
2557            destroyedInterfacesDestroyedListeners[i].validate();
2558        }
2559        return iface;
2560    }
2561
2562    private int getType(IWifiIface iface) throws Exception {
2563        Mutable<Integer> typeResp = new Mutable<>();
2564        iface.getType((WifiStatus status, int type) -> {
2565            typeResp.value = type;
2566        });
2567        return typeResp.value;
2568    }
2569
2570    private String getName(IWifiIface iface) throws Exception {
2571        Mutable<String> nameResp = new Mutable<>();
2572        iface.getName((WifiStatus status, String name) -> {
2573            nameResp.value = name;
2574        });
2575        return nameResp.value;
2576    }
2577
2578    private WifiStatus getStatus(int code) {
2579        WifiStatus status = new WifiStatus();
2580        status.code = code;
2581        return status;
2582    }
2583
2584    private static class InterfaceDestroyedListenerWithIfaceName {
2585        private final String mIfaceName;
2586        @Mock private final InterfaceDestroyedListener mListener;
2587
2588        InterfaceDestroyedListenerWithIfaceName(
2589                String ifaceName, InterfaceDestroyedListener listener) {
2590            mIfaceName = ifaceName;
2591            mListener = listener;
2592        }
2593
2594        public void validate() {
2595            verify(mListener).onDestroyed(mIfaceName);
2596        }
2597    }
2598
2599    private static class Mutable<E> {
2600        public E value;
2601
2602        Mutable() {
2603            value = null;
2604        }
2605
2606        Mutable(E value) {
2607            this.value = value;
2608        }
2609    }
2610
2611    // Answer objects
2612    private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
2613        private WifiStatus mStatus;
2614        private ArrayList<Integer> mChipIds;
2615
2616        GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
2617            mStatus = status;
2618            mChipIds = chipIds;
2619        }
2620
2621        public void answer(IWifi.getChipIdsCallback cb) {
2622            cb.onValues(mStatus, mChipIds);
2623        }
2624    }
2625
2626    private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
2627        private WifiStatus mStatus;
2628        private IWifiChip mChip;
2629
2630        GetChipAnswer(WifiStatus status, IWifiChip chip) {
2631            mStatus = status;
2632            mChip = chip;
2633        }
2634
2635        public void answer(int chipId, IWifi.getChipCallback cb) {
2636            cb.onValues(mStatus, mChip);
2637        }
2638    }
2639
2640    private class GetIdAnswer extends MockAnswerUtil.AnswerWithArguments {
2641        private ChipMockBase mChipMockBase;
2642
2643        GetIdAnswer(ChipMockBase chipMockBase) {
2644            mChipMockBase = chipMockBase;
2645        }
2646
2647        public void answer(IWifiChip.getIdCallback cb) {
2648            cb.onValues(mStatusOk, mChipMockBase.chipId);
2649        }
2650    }
2651
2652    private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments {
2653        private ChipMockBase mChipMockBase;
2654
2655        GetAvailableModesAnswer(ChipMockBase chipMockBase) {
2656            mChipMockBase = chipMockBase;
2657        }
2658
2659        public void answer(IWifiChip.getAvailableModesCallback cb) {
2660            cb.onValues(mStatusOk, mChipMockBase.availableModes);
2661        }
2662    }
2663
2664    private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments {
2665        private ChipMockBase mChipMockBase;
2666
2667        GetModeAnswer(ChipMockBase chipMockBase) {
2668            mChipMockBase = chipMockBase;
2669        }
2670
2671        public void answer(IWifiChip.getModeCallback cb) {
2672            cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
2673                    : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
2674        }
2675    }
2676
2677    private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments {
2678        private ChipMockBase mChipMockBase;
2679
2680        ConfigureChipAnswer(ChipMockBase chipMockBase) {
2681            mChipMockBase = chipMockBase;
2682        }
2683
2684        public WifiStatus answer(int chipMode) {
2685            mChipMockBase.chipModeId = chipMode;
2686            return mStatusOk;
2687        }
2688    }
2689
2690    private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
2691        private ChipMockBase mChipMockBase;
2692
2693        GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
2694            mChipMockBase = chipMockBase;
2695        }
2696
2697        public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
2698            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
2699        }
2700
2701        public void answer(IWifiChip.getApIfaceNamesCallback cb) {
2702            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
2703        }
2704
2705        public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
2706            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
2707        }
2708
2709        public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
2710            cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
2711        }
2712    }
2713
2714    private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
2715        private ChipMockBase mChipMockBase;
2716
2717        GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
2718            mChipMockBase = chipMockBase;
2719        }
2720
2721        public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
2722            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
2723            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
2724        }
2725
2726        public void answer(String name, IWifiChip.getApIfaceCallback cb) {
2727            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
2728            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
2729        }
2730
2731        public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
2732            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
2733            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
2734        }
2735
2736        public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
2737            IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
2738            cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
2739        }
2740    }
2741
2742    private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
2743        private ChipMockBase mChipMockBase;
2744        private WifiStatus mStatus;
2745        private IWifiIface mWifiIface;
2746
2747        CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
2748            mChipMockBase = chipMockBase;
2749            mStatus = status;
2750            mWifiIface = wifiIface;
2751        }
2752
2753        private void addInterfaceInfo(int type) {
2754            if (mStatus.code == WifiStatusCode.SUCCESS) {
2755                try {
2756                    mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
2757                    mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
2758                } catch (Exception e) {
2759                    // do nothing
2760                }
2761            }
2762        }
2763
2764        public void answer(IWifiChip.createStaIfaceCallback cb) {
2765            cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
2766            addInterfaceInfo(IfaceType.STA);
2767        }
2768
2769        public void answer(IWifiChip.createApIfaceCallback cb) {
2770            cb.onValues(mStatus, (IWifiApIface) mWifiIface);
2771            addInterfaceInfo(IfaceType.AP);
2772        }
2773
2774        public void answer(IWifiChip.createP2pIfaceCallback cb) {
2775            cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
2776            addInterfaceInfo(IfaceType.P2P);
2777        }
2778
2779        public void answer(IWifiChip.createNanIfaceCallback cb) {
2780            cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
2781            addInterfaceInfo(IfaceType.NAN);
2782        }
2783    }
2784
2785    private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
2786        private ChipMockBase mChipMockBase;
2787        private int mType;
2788
2789        RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
2790            mChipMockBase = chipMockBase;
2791            mType = type;
2792        }
2793
2794        private WifiStatus removeIface(int type, String ifname) {
2795            try {
2796                if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
2797                    return mStatusFail;
2798                }
2799                if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
2800                    return mStatusFail;
2801                }
2802            } catch (Exception e) {
2803                return mStatusFail;
2804            }
2805            return mStatusOk;
2806        }
2807
2808        public WifiStatus answer(String ifname) {
2809            return removeIface(mType, ifname);
2810        }
2811    }
2812
2813    private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments {
2814        private String mName;
2815
2816        GetNameAnswer(String name) {
2817            mName = name;
2818        }
2819
2820        public void answer(IWifiIface.getNameCallback cb) {
2821            cb.onValues(mStatusOk, mName);
2822        }
2823    }
2824
2825    private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
2826        private int mType;
2827
2828        GetTypeAnswer(int type) {
2829            mType = type;
2830        }
2831
2832        public void answer(IWifiIface.getTypeCallback cb) {
2833            cb.onValues(mStatusOk, mType);
2834        }
2835    }
2836
2837    // chip configuration
2838
2839    private static final int CHIP_MOCK_V1 = 0;
2840    private static final int CHIP_MOCK_V2 = 1;
2841    private static final int CHIP_MOCK_V3 = 2;
2842    private static final int CHIP_MOCK_V4 = 3;
2843
2844    private class ChipMockBase {
2845        public int chipMockId;
2846
2847        public IWifiChip chip;
2848        public int chipId;
2849        public boolean chipModeValid = false;
2850        public int chipModeId = -1000;
2851        public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
2852        public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
2853
2854        public ArrayList<IWifiChip.ChipMode> availableModes;
2855
2856        void initialize() throws Exception {
2857            chip = mock(IWifiChip.class);
2858
2859            interfaceNames.put(IfaceType.STA, new ArrayList<>());
2860            interfaceNames.put(IfaceType.AP, new ArrayList<>());
2861            interfaceNames.put(IfaceType.P2P, new ArrayList<>());
2862            interfaceNames.put(IfaceType.NAN, new ArrayList<>());
2863
2864            interfacesByName.put(IfaceType.STA, new HashMap<>());
2865            interfacesByName.put(IfaceType.AP, new HashMap<>());
2866            interfacesByName.put(IfaceType.P2P, new HashMap<>());
2867            interfacesByName.put(IfaceType.NAN, new HashMap<>());
2868
2869            when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
2870                    mStatusOk);
2871            when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
2872            doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class));
2873            doAnswer(new GetModeAnswer(this)).when(chip).getMode(
2874                    any(IWifiChip.getModeCallback.class));
2875            GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
2876            doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
2877                    any(IWifiChip.getStaIfaceNamesCallback.class));
2878            doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
2879                    any(IWifiChip.getApIfaceNamesCallback.class));
2880            doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
2881                    any(IWifiChip.getP2pIfaceNamesCallback.class));
2882            doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
2883                    any(IWifiChip.getNanIfaceNamesCallback.class));
2884            GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
2885            doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
2886                    any(IWifiChip.getStaIfaceCallback.class));
2887            doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
2888                    any(IWifiChip.getApIfaceCallback.class));
2889            doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
2890                    any(IWifiChip.getP2pIfaceCallback.class));
2891            doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
2892                    any(IWifiChip.getNanIfaceCallback.class));
2893            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
2894                    anyString());
2895            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
2896                    anyString());
2897            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
2898                    anyString());
2899            doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
2900                    anyString());
2901        }
2902    }
2903
2904    // test chip configuration V1:
2905    // mode: STA + (NAN || P2P)
2906    // mode: AP
2907    private class TestChipV1 extends ChipMockBase {
2908        static final int STA_CHIP_MODE_ID = 0;
2909        static final int AP_CHIP_MODE_ID = 1;
2910
2911        void initialize() throws Exception {
2912            super.initialize();
2913
2914            chipMockId = CHIP_MOCK_V1;
2915
2916            // chip Id configuration
2917            ArrayList<Integer> chipIds;
2918            chipId = 10;
2919            chipIds = new ArrayList<>();
2920            chipIds.add(chipId);
2921            doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
2922                    any(IWifi.getChipIdsCallback.class));
2923
2924            doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
2925                    any(IWifi.getChipCallback.class));
2926
2927            // initialize dummy chip modes
2928            IWifiChip.ChipMode cm;
2929            IWifiChip.ChipIfaceCombination cic;
2930            IWifiChip.ChipIfaceCombinationLimit cicl;
2931
2932            //   Mode 0: 1xSTA + 1x{P2P,NAN}
2933            //   Mode 1: 1xAP
2934            availableModes = new ArrayList<>();
2935            cm = new IWifiChip.ChipMode();
2936            cm.id = STA_CHIP_MODE_ID;
2937
2938            cic = new IWifiChip.ChipIfaceCombination();
2939
2940            cicl = new IWifiChip.ChipIfaceCombinationLimit();
2941            cicl.maxIfaces = 1;
2942            cicl.types.add(IfaceType.STA);
2943            cic.limits.add(cicl);
2944
2945            cicl = new IWifiChip.ChipIfaceCombinationLimit();
2946            cicl.maxIfaces = 1;
2947            cicl.types.add(IfaceType.P2P);
2948            cicl.types.add(IfaceType.NAN);
2949            cic.limits.add(cicl);
2950            cm.availableCombinations.add(cic);
2951            availableModes.add(cm);
2952
2953            cm = new IWifiChip.ChipMode();
2954            cm.id = AP_CHIP_MODE_ID;
2955            cic = new IWifiChip.ChipIfaceCombination();
2956            cicl = new IWifiChip.ChipIfaceCombinationLimit();
2957            cicl.maxIfaces = 1;
2958            cicl.types.add(IfaceType.AP);
2959            cic.limits.add(cicl);
2960            cm.availableCombinations.add(cic);
2961            availableModes.add(cm);
2962
2963            doAnswer(new GetAvailableModesAnswer(this)).when(chip)
2964                    .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
2965        }
2966    }
2967
2968    // test chip configuration V2:
2969    // mode: STA + (STA || AP) + (NAN || P2P)
2970    private class TestChipV2 extends ChipMockBase {
2971        // only mode (different number from any in TestChipV1 so can catch test errors)
2972        static final int CHIP_MODE_ID = 5;
2973
2974        void initialize() throws Exception {
2975            super.initialize();
2976
2977            chipMockId = CHIP_MOCK_V2;
2978
2979            // chip Id configuration
2980            ArrayList<Integer> chipIds;
2981            chipId = 12;
2982            chipIds = new ArrayList<>();
2983            chipIds.add(chipId);
2984            doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
2985                    any(IWifi.getChipIdsCallback.class));
2986
2987            doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(12),
2988                    any(IWifi.getChipCallback.class));
2989
2990            // initialize dummy chip modes
2991            IWifiChip.ChipMode cm;
2992            IWifiChip.ChipIfaceCombination cic;
2993            IWifiChip.ChipIfaceCombinationLimit cicl;
2994
2995            //   Mode 0 (only one): 1xSTA + 1x{STA,AP} + 1x{P2P,NAN}
2996            availableModes = new ArrayList<>();
2997            cm = new IWifiChip.ChipMode();
2998            cm.id = CHIP_MODE_ID;
2999
3000            cic = new IWifiChip.ChipIfaceCombination();
3001
3002            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3003            cicl.maxIfaces = 1;
3004            cicl.types.add(IfaceType.STA);
3005            cic.limits.add(cicl);
3006
3007            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3008            cicl.maxIfaces = 1;
3009            cicl.types.add(IfaceType.STA);
3010            cicl.types.add(IfaceType.AP);
3011            cic.limits.add(cicl);
3012
3013            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3014            cicl.maxIfaces = 1;
3015            cicl.types.add(IfaceType.P2P);
3016            cicl.types.add(IfaceType.NAN);
3017            cic.limits.add(cicl);
3018            cm.availableCombinations.add(cic);
3019            availableModes.add(cm);
3020
3021            doAnswer(new GetAvailableModesAnswer(this)).when(chip)
3022                    .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
3023        }
3024    }
3025
3026    // test chip configuration V3:
3027    // mode:
3028    //    STA + (STA || AP)
3029    //    STA + (NAN || P2P)
3030    private class TestChipV3 extends ChipMockBase {
3031        // only mode (different number from any in other TestChips so can catch test errors)
3032        static final int CHIP_MODE_ID = 7;
3033
3034        void initialize() throws Exception {
3035            super.initialize();
3036
3037            chipMockId = CHIP_MOCK_V3;
3038
3039            // chip Id configuration
3040            ArrayList<Integer> chipIds;
3041            chipId = 15;
3042            chipIds = new ArrayList<>();
3043            chipIds.add(chipId);
3044            doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
3045                    any(IWifi.getChipIdsCallback.class));
3046
3047            doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(15),
3048                    any(IWifi.getChipCallback.class));
3049
3050            // initialize dummy chip modes
3051            IWifiChip.ChipMode cm;
3052            IWifiChip.ChipIfaceCombination cic;
3053            IWifiChip.ChipIfaceCombinationLimit cicl;
3054
3055            //   Mode 0 (only one): 1xSTA + 1x{STA,AP}, 1xSTA + 1x{P2P,NAN}
3056            availableModes = new ArrayList<>();
3057            cm = new IWifiChip.ChipMode();
3058            cm.id = CHIP_MODE_ID;
3059
3060            cic = new IWifiChip.ChipIfaceCombination();
3061
3062            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3063            cicl.maxIfaces = 1;
3064            cicl.types.add(IfaceType.STA);
3065            cic.limits.add(cicl);
3066
3067            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3068            cicl.maxIfaces = 1;
3069            cicl.types.add(IfaceType.STA);
3070            cicl.types.add(IfaceType.AP);
3071            cic.limits.add(cicl);
3072
3073            cm.availableCombinations.add(cic);
3074
3075            cic = new IWifiChip.ChipIfaceCombination();
3076
3077            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3078            cicl.maxIfaces = 1;
3079            cicl.types.add(IfaceType.STA);
3080            cic.limits.add(cicl);
3081
3082            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3083            cicl.maxIfaces = 1;
3084            cicl.types.add(IfaceType.P2P);
3085            cicl.types.add(IfaceType.NAN);
3086            cic.limits.add(cicl);
3087
3088            cm.availableCombinations.add(cic);
3089            availableModes.add(cm);
3090
3091            doAnswer(new GetAvailableModesAnswer(this)).when(chip)
3092                    .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
3093        }
3094    }
3095
3096    // test chip configuration V4:
3097    // mode:
3098    //    STA + AP
3099    //    STA + (NAN || P2P)
3100    private class TestChipV4 extends ChipMockBase {
3101        // only mode (different number from any in other TestChips so can catch test errors)
3102        static final int CHIP_MODE_ID = 15;
3103
3104        void initialize() throws Exception {
3105            super.initialize();
3106
3107            chipMockId = CHIP_MOCK_V4;
3108
3109            // chip Id configuration
3110            ArrayList<Integer> chipIds;
3111            chipId = 23;
3112            chipIds = new ArrayList<>();
3113            chipIds.add(chipId);
3114            doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
3115                    any(IWifi.getChipIdsCallback.class));
3116
3117            doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(23),
3118                    any(IWifi.getChipCallback.class));
3119
3120            // initialize dummy chip modes
3121            IWifiChip.ChipMode cm;
3122            IWifiChip.ChipIfaceCombination cic;
3123            IWifiChip.ChipIfaceCombinationLimit cicl;
3124
3125            //   Mode 0 (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
3126            availableModes = new ArrayList<>();
3127            cm = new IWifiChip.ChipMode();
3128            cm.id = CHIP_MODE_ID;
3129
3130            cic = new IWifiChip.ChipIfaceCombination();
3131
3132            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3133            cicl.maxIfaces = 1;
3134            cicl.types.add(IfaceType.STA);
3135            cic.limits.add(cicl);
3136
3137            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3138            cicl.maxIfaces = 1;
3139            cicl.types.add(IfaceType.AP);
3140            cic.limits.add(cicl);
3141
3142            cm.availableCombinations.add(cic);
3143
3144            cic = new IWifiChip.ChipIfaceCombination();
3145
3146            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3147            cicl.maxIfaces = 1;
3148            cicl.types.add(IfaceType.STA);
3149            cic.limits.add(cicl);
3150
3151            cicl = new IWifiChip.ChipIfaceCombinationLimit();
3152            cicl.maxIfaces = 1;
3153            cicl.types.add(IfaceType.P2P);
3154            cicl.types.add(IfaceType.NAN);
3155            cic.limits.add(cicl);
3156
3157            cm.availableCombinations.add(cic);
3158            availableModes.add(cm);
3159
3160            doAnswer(new GetAvailableModesAnswer(this)).when(chip)
3161                    .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
3162        }
3163    }
3164}
3165