• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
20 
21 import static junit.framework.Assert.assertEquals;
22 
23 import static org.hamcrest.core.IsEqual.equalTo;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.mockito.Matchers.any;
27 import static org.mockito.Matchers.anyInt;
28 import static org.mockito.Matchers.anyLong;
29 import static org.mockito.Matchers.anyString;
30 import static org.mockito.Matchers.eq;
31 import static org.mockito.Mockito.doAnswer;
32 import static org.mockito.Mockito.inOrder;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.verifyNoMoreInteractions;
37 import static org.mockito.Mockito.when;
38 
39 import android.app.test.MockAnswerUtil;
40 import android.hardware.wifi.V1_0.IWifi;
41 import android.hardware.wifi.V1_0.IWifiApIface;
42 import android.hardware.wifi.V1_0.IWifiChip;
43 import android.hardware.wifi.V1_0.IWifiChipEventCallback;
44 import android.hardware.wifi.V1_0.IWifiEventCallback;
45 import android.hardware.wifi.V1_0.IWifiIface;
46 import android.hardware.wifi.V1_0.IWifiNanIface;
47 import android.hardware.wifi.V1_0.IWifiP2pIface;
48 import android.hardware.wifi.V1_0.IWifiStaIface;
49 import android.hardware.wifi.V1_0.IfaceType;
50 import android.hardware.wifi.V1_0.WifiStatus;
51 import android.hardware.wifi.V1_0.WifiStatusCode;
52 import android.hidl.manager.V1_0.IServiceManager;
53 import android.hidl.manager.V1_0.IServiceNotification;
54 import android.os.IHwBinder;
55 import android.os.test.TestLooper;
56 import android.util.Log;
57 
58 import org.hamcrest.core.IsNull;
59 import org.junit.After;
60 import org.junit.Before;
61 import org.junit.Rule;
62 import org.junit.Test;
63 import org.junit.rules.ErrorCollector;
64 import org.mockito.ArgumentCaptor;
65 import org.mockito.InOrder;
66 import org.mockito.Mock;
67 import org.mockito.MockitoAnnotations;
68 
69 import java.io.PrintWriter;
70 import java.io.StringWriter;
71 import java.util.ArrayList;
72 import java.util.HashMap;
73 import java.util.HashSet;
74 import java.util.Map;
75 import java.util.Set;
76 
77 /**
78  * Unit test harness for HalDeviceManagerTest.
79  */
80 public class HalDeviceManagerTest {
81     private HalDeviceManager mDut;
82     @Mock IServiceManager mServiceManagerMock;
83     @Mock IWifi mWifiMock;
84     @Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock;
85     private TestLooper mTestLooper;
86     private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
87             ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
88     private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
89             ArgumentCaptor.forClass(IServiceNotification.Stub.class);
90     private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
91             IWifiEventCallback.class);
92     private InOrder mInOrder;
93     @Rule public ErrorCollector collector = new ErrorCollector();
94     private WifiStatus mStatusOk;
95     private WifiStatus mStatusFail;
96 
97     private class HalDeviceManagerSpy extends HalDeviceManager {
98         @Override
getWifiServiceMockable()99         protected IWifi getWifiServiceMockable() {
100             return mWifiMock;
101         }
102 
103         @Override
getServiceManagerMockable()104         protected IServiceManager getServiceManagerMockable() {
105             return mServiceManagerMock;
106         }
107     }
108 
109     @Before
before()110     public void before() throws Exception {
111         MockitoAnnotations.initMocks(this);
112 
113         mTestLooper = new TestLooper();
114 
115         // initialize dummy status objects
116         mStatusOk = getStatus(WifiStatusCode.SUCCESS);
117         mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
118 
119         when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
120                 anyLong())).thenReturn(true);
121         when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
122                 any(IServiceNotification.Stub.class))).thenReturn(true);
123         when(mServiceManagerMock.getTransport(
124                 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
125                 .thenReturn(IServiceManager.Transport.HWBINDER);
126         when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
127                 true);
128         when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
129         when(mWifiMock.start()).thenReturn(mStatusOk);
130         when(mWifiMock.stop()).thenReturn(mStatusOk);
131 
132         mDut = new HalDeviceManagerSpy();
133     }
134 
135     /**
136      * Print out the dump of the device manager after each test. Not used in test validation
137      * (internal state) - but can help in debugging failed tests.
138      */
139     @After
after()140     public void after() throws Exception {
141         dumpDut("after: ");
142     }
143 
144     /**
145      * Test basic startup flow:
146      * - IServiceManager registrations
147      * - IWifi registrations
148      * - IWifi startup delayed
149      * - Start Wi-Fi -> onStart
150      * - Stop Wi-Fi -> onStop
151      */
152     @Test
testStartStopFlow()153     public void testStartStopFlow() throws Exception {
154         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
155         executeAndValidateInitializationSequence();
156         executeAndValidateStartupSequence();
157 
158         // act: stop Wi-Fi
159         mDut.stop();
160         mTestLooper.dispatchAll();
161 
162         // verify: onStop called
163         mInOrder.verify(mWifiMock).stop();
164         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
165 
166         verifyNoMoreInteractions(mManagerStatusListenerMock);
167     }
168 
169     /**
170      * Test the service manager notification coming in after
171      * {@link HalDeviceManager#initIWifiIfNecessary()} is already invoked as a part of
172      * {@link HalDeviceManager#initialize()}.
173      */
174     @Test
testServiceRegisterationAfterInitialize()175     public void testServiceRegisterationAfterInitialize() throws Exception {
176         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
177         executeAndValidateInitializationSequence();
178 
179         // This should now be ignored since IWifi is already non-null.
180         mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
181 
182         verifyNoMoreInteractions(mManagerStatusListenerMock, mWifiMock, mServiceManagerMock);
183     }
184 
185     /**
186      * Validate that multiple callback registrations are called and that duplicate ones are
187      * only called once.
188      */
189     @Test
testMultipleCallbackRegistrations()190     public void testMultipleCallbackRegistrations() throws Exception {
191         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
192         executeAndValidateInitializationSequence();
193 
194         // register another 2 callbacks - one of them twice
195         HalDeviceManager.ManagerStatusListener callback1 = mock(
196                 HalDeviceManager.ManagerStatusListener.class);
197         HalDeviceManager.ManagerStatusListener callback2 = mock(
198                 HalDeviceManager.ManagerStatusListener.class);
199         mDut.registerStatusListener(callback2, mTestLooper.getLooper());
200         mDut.registerStatusListener(callback1, mTestLooper.getLooper());
201         mDut.registerStatusListener(callback2, mTestLooper.getLooper());
202 
203         // startup
204         executeAndValidateStartupSequence();
205 
206         // verify
207         verify(callback1).onStatusChanged();
208         verify(callback2).onStatusChanged();
209 
210         verifyNoMoreInteractions(mManagerStatusListenerMock, callback1, callback2);
211     }
212 
213     /**
214      * Validate IWifi death listener and registration flow.
215      */
216     @Test
testWifiDeathAndRegistration()217     public void testWifiDeathAndRegistration() throws Exception {
218         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
219         executeAndValidateInitializationSequence();
220         executeAndValidateStartupSequence();
221 
222         // act: IWifi service death
223         mDeathRecipientCaptor.getValue().serviceDied(0);
224         mTestLooper.dispatchAll();
225 
226         // verify: getting onStop
227         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
228 
229         // act: service startup
230         mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
231 
232         // verify: initialization of IWifi
233         mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
234         mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
235 
236         // act: start
237         collector.checkThat(mDut.start(), equalTo(true));
238         mWifiEventCallbackCaptor.getValue().onStart();
239         mTestLooper.dispatchAll();
240 
241         // verify: service and callback calls
242         mInOrder.verify(mWifiMock).start();
243         mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
244 
245         verifyNoMoreInteractions(mManagerStatusListenerMock);
246     }
247 
248     /**
249      * Validate IWifi onFailure causes notification
250      */
251     @Test
testWifiFail()252     public void testWifiFail() throws Exception {
253         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
254         executeAndValidateInitializationSequence();
255         executeAndValidateStartupSequence();
256 
257         // act: IWifi failure
258         mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
259         mTestLooper.dispatchAll();
260 
261         // verify: getting onStop
262         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
263 
264         // act: start again
265         collector.checkThat(mDut.start(), equalTo(true));
266         mWifiEventCallbackCaptor.getValue().onStart();
267         mTestLooper.dispatchAll();
268 
269         // verify: service and callback calls
270         mInOrder.verify(mWifiMock).start();
271         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
272 
273         verifyNoMoreInteractions(mManagerStatusListenerMock);
274     }
275 
276     /**
277      * Validate creation of STA interface from blank start-up. The remove interface.
278      */
279     @Test
testCreateStaInterfaceNoInitMode()280     public void testCreateStaInterfaceNoInitMode() throws Exception {
281         final String name = "sta0";
282 
283         BaselineChip chipMock = new BaselineChip();
284         chipMock.initialize();
285         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
286                 mManagerStatusListenerMock);
287         executeAndValidateInitializationSequence();
288         executeAndValidateStartupSequence();
289 
290         HalDeviceManager.InterfaceDestroyedListener idl = mock(
291                 HalDeviceManager.InterfaceDestroyedListener.class);
292         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
293                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
294 
295         IWifiStaIface iface = (IWifiStaIface) validateInterfaceSequence(chipMock,
296                 false, // chipModeValid
297                 -1000, // chipModeId (only used if chipModeValid is true)
298                 IfaceType.STA, // ifaceTypeToCreate
299                 name, // ifaceName
300                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
301                 null, // tearDownList
302                 idl, // destroyedListener
303                 iafrl // availableListener
304         );
305         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
306 
307         // act: remove interface
308         mDut.removeIface(iface);
309         mTestLooper.dispatchAll();
310 
311         // verify: callback triggered
312         mInOrder.verify(chipMock.chip).removeStaIface(name);
313         verify(idl).onDestroyed();
314         verify(iafrl).onAvailableForRequest();
315 
316         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
317     }
318 
319     /**
320      * Validate creation of AP interface from blank start-up. The remove interface.
321      */
322     @Test
testCreateApInterfaceNoInitMode()323     public void testCreateApInterfaceNoInitMode() throws Exception {
324         final String name = "ap0";
325 
326         BaselineChip chipMock = new BaselineChip();
327         chipMock.initialize();
328         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
329                 mManagerStatusListenerMock);
330         executeAndValidateInitializationSequence();
331         executeAndValidateStartupSequence();
332 
333         HalDeviceManager.InterfaceDestroyedListener idl = mock(
334                 HalDeviceManager.InterfaceDestroyedListener.class);
335         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
336                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
337 
338         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
339                 false, // chipModeValid
340                 -1000, // chipModeId (only used if chipModeValid is true)
341                 IfaceType.AP, // ifaceTypeToCreate
342                 name, // ifaceName
343                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
344                 null, // tearDownList
345                 idl, // destroyedListener
346                 iafrl // availableListener
347         );
348         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
349 
350         // act: remove interface
351         mDut.removeIface(iface);
352         mTestLooper.dispatchAll();
353 
354         // verify: callback triggered
355         mInOrder.verify(chipMock.chip).removeApIface(name);
356         verify(idl).onDestroyed();
357         verify(iafrl).onAvailableForRequest();
358 
359         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
360     }
361 
362     /**
363      * Validate creation of P2P interface from blank start-up. The remove interface.
364      */
365     @Test
testCreateP2pInterfaceNoInitMode()366     public void testCreateP2pInterfaceNoInitMode() throws Exception {
367         final String name = "p2p0";
368 
369         BaselineChip chipMock = new BaselineChip();
370         chipMock.initialize();
371         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
372                 mManagerStatusListenerMock);
373         executeAndValidateInitializationSequence();
374         executeAndValidateStartupSequence();
375 
376         HalDeviceManager.InterfaceDestroyedListener idl = mock(
377                 HalDeviceManager.InterfaceDestroyedListener.class);
378         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
379                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
380 
381         IWifiP2pIface iface = (IWifiP2pIface) validateInterfaceSequence(chipMock,
382                 false, // chipModeValid
383                 -1000, // chipModeId (only used if chipModeValid is true)
384                 IfaceType.P2P, // ifaceTypeToCreate
385                 name, // ifaceName
386                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
387                 null, // tearDownList
388                 idl, // destroyedListener
389                 iafrl // availableListener
390         );
391         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
392 
393         // act: remove interface
394         mDut.removeIface(iface);
395         mTestLooper.dispatchAll();
396 
397         // verify: callback triggered
398         mInOrder.verify(chipMock.chip).removeP2pIface(name);
399         verify(idl).onDestroyed();
400         verify(iafrl).onAvailableForRequest();
401 
402         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
403     }
404 
405     /**
406      * Validate creation of NAN interface from blank start-up. The remove interface.
407      */
408     @Test
testCreateNanInterfaceNoInitMode()409     public void testCreateNanInterfaceNoInitMode() throws Exception {
410         final String name = "nan0";
411 
412         BaselineChip chipMock = new BaselineChip();
413         chipMock.initialize();
414         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
415                 mManagerStatusListenerMock);
416         executeAndValidateInitializationSequence();
417         executeAndValidateStartupSequence();
418 
419         HalDeviceManager.InterfaceDestroyedListener idl = mock(
420                 HalDeviceManager.InterfaceDestroyedListener.class);
421         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
422                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
423 
424         IWifiNanIface iface = (IWifiNanIface) validateInterfaceSequence(chipMock,
425                 false, // chipModeValid
426                 -1000, // chipModeId (only used if chipModeValid is true)
427                 IfaceType.NAN, // ifaceTypeToCreate
428                 name, // ifaceName
429                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
430                 null, // tearDownList
431                 idl, // destroyedListener
432                 iafrl // availableListener
433         );
434         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
435 
436         // act: remove interface
437         mDut.removeIface(iface);
438         mTestLooper.dispatchAll();
439 
440         // verify: callback triggered
441         mInOrder.verify(chipMock.chip).removeNanIface(name);
442         verify(idl).onDestroyed();
443         verify(iafrl).onAvailableForRequest();
444 
445         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
446     }
447 
448     /**
449      * Validate creation of AP interface when in STA mode - but with no interface created. Expect
450      * a change in chip mode.
451      */
452     @Test
testCreateApWithStaModeUp()453     public void testCreateApWithStaModeUp() throws Exception {
454         final String name = "ap0";
455 
456         BaselineChip chipMock = new BaselineChip();
457         chipMock.initialize();
458         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
459                 mManagerStatusListenerMock);
460         executeAndValidateInitializationSequence();
461         executeAndValidateStartupSequence();
462 
463         HalDeviceManager.InterfaceDestroyedListener idl = mock(
464                 HalDeviceManager.InterfaceDestroyedListener.class);
465         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
466                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
467 
468         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
469                 true, // chipModeValid
470                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
471                 IfaceType.AP, // ifaceTypeToCreate
472                 name, // ifaceName
473                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
474                 null, // tearDownList
475                 idl, // destroyedListener
476                 iafrl // availableListener
477         );
478         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
479 
480         // act: stop Wi-Fi
481         mDut.stop();
482         mTestLooper.dispatchAll();
483 
484         // verify: callback triggered
485         verify(idl).onDestroyed();
486         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
487 
488         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
489     }
490 
491     /**
492      * Validate creation of AP interface when in AP mode - but with no interface created. Expect
493      * no change in chip mode.
494      */
495     @Test
testCreateApWithApModeUp()496     public void testCreateApWithApModeUp() throws Exception {
497         final String name = "ap0";
498 
499         BaselineChip chipMock = new BaselineChip();
500         chipMock.initialize();
501         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
502                 mManagerStatusListenerMock);
503         executeAndValidateInitializationSequence();
504         executeAndValidateStartupSequence();
505 
506         HalDeviceManager.InterfaceDestroyedListener idl = mock(
507                 HalDeviceManager.InterfaceDestroyedListener.class);
508         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
509                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
510 
511         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
512                 true, // chipModeValid
513                 BaselineChip.AP_CHIP_MODE_ID, // chipModeId
514                 IfaceType.AP, // ifaceTypeToCreate
515                 name, // ifaceName
516                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
517                 null, // tearDownList
518                 idl, // destroyedListener
519                 iafrl // availableListener
520         );
521         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
522 
523         // act: stop Wi-Fi
524         mDut.stop();
525         mTestLooper.dispatchAll();
526 
527         // verify: callback triggered
528         verify(idl).onDestroyed();
529         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
530 
531         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
532     }
533 
534     /**
535      * Validate AP up/down creation of AP interface when a STA already created. Expect:
536      * - STA created
537      * - P2P created
538      * - When AP requested:
539      *   - STA & P2P torn down
540      *   - AP created
541      * - P2P creation refused
542      * - Request STA: will tear down AP
543      * - When AP destroyed:
544      *   - Get p2p available listener callback
545      *   - Can create P2P when requested
546      * - Create P2P
547      * - Request NAN: will get refused
548      * - Tear down P2P:
549      *    - should get nan available listener callback
550      *    - Can create NAN when requested
551      */
552     @Test
testCreateSameAndDiffPriorities()553     public void testCreateSameAndDiffPriorities() throws Exception {
554         BaselineChip chipMock = new BaselineChip();
555         chipMock.initialize();
556         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
557                 mManagerStatusListenerMock);
558         executeAndValidateInitializationSequence();
559         executeAndValidateStartupSequence();
560 
561         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
562                 HalDeviceManager.InterfaceDestroyedListener.class);
563         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
564                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
565 
566         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock(
567                 HalDeviceManager.InterfaceDestroyedListener.class);
568 
569         HalDeviceManager.InterfaceDestroyedListener apDestroyedListener = mock(
570                 HalDeviceManager.InterfaceDestroyedListener.class);
571         HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
572                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
573 
574         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
575                 HalDeviceManager.InterfaceDestroyedListener.class);
576         HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
577                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
578 
579         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener2 = mock(
580                 HalDeviceManager.InterfaceDestroyedListener.class);
581 
582         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
583                 HalDeviceManager.InterfaceDestroyedListener.class);
584         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
585                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
586 
587         // Request STA
588         IWifiIface staIface = validateInterfaceSequence(chipMock,
589                 false, // chipModeValid
590                 -1000, // chipModeId (only used if chipModeValid is true)
591                 IfaceType.STA, // ifaceTypeToCreate
592                 "sta0", // ifaceName
593                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
594                 null, // tearDownList
595                 staDestroyedListener, // destroyedListener
596                 staAvailListener // availableListener
597         );
598         collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
599 
600         // register additional InterfaceDestroyedListeners - including a duplicate (verify that
601         // only called once!)
602         mDut.registerDestroyedListener(staIface, staDestroyedListener2, mTestLooper.getLooper());
603         mDut.registerDestroyedListener(staIface, staDestroyedListener, mTestLooper.getLooper());
604 
605         // Request P2P
606         IWifiIface p2pIface = validateInterfaceSequence(chipMock,
607                 true, // chipModeValid
608                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
609                 IfaceType.P2P, // ifaceTypeToCreate
610                 "p2p0", // ifaceName
611                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
612                 null, // tearDownList
613                 p2pDestroyedListener, // destroyedListener
614                 p2pAvailListener // availableListener
615         );
616         collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
617 
618         // Request AP
619         IWifiIface apIface = validateInterfaceSequence(chipMock,
620                 true, // chipModeValid
621                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
622                 IfaceType.AP, // ifaceTypeToCreate
623                 "ap0", // ifaceName
624                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
625                 new IWifiIface[]{staIface, p2pIface}, // tearDownList
626                 apDestroyedListener, // destroyedListener
627                 apAvailListener, // availableListener
628                 // destroyedInterfacesDestroyedListeners...
629                 staDestroyedListener, staDestroyedListener2, p2pDestroyedListener
630         );
631         collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue());
632 
633         // Request P2P: expect failure
634         p2pIface = mDut.createP2pIface(p2pDestroyedListener, mTestLooper.getLooper());
635         collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue());
636 
637         // Request STA: expect success
638         staIface = validateInterfaceSequence(chipMock,
639                 true, // chipModeValid
640                 BaselineChip.AP_CHIP_MODE_ID, // chipModeId
641                 IfaceType.STA, // ifaceTypeToCreate
642                 "sta0", // ifaceName
643                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
644                 null, // tearDownList
645                 staDestroyedListener, // destroyedListener
646                 staAvailListener, // availableListener
647                 apDestroyedListener // destroyedInterfacesDestroyedListeners...
648         );
649         collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
650 
651         mTestLooper.dispatchAll();
652         verify(apDestroyedListener).onDestroyed();
653 
654         // Request P2P: expect success now
655         p2pIface = validateInterfaceSequence(chipMock,
656                 true, // chipModeValid
657                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
658                 IfaceType.P2P, // ifaceTypeToCreate
659                 "p2p0", // ifaceName
660                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
661                 null, // tearDownList
662                 p2pDestroyedListener2, // destroyedListener
663                 p2pAvailListener // availableListener
664         );
665 
666         // Request NAN: should fail
667         IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
668         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
669                 mTestLooper.getLooper());
670         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
671 
672         // Tear down P2P
673         mDut.removeIface(p2pIface);
674         mTestLooper.dispatchAll();
675 
676         verify(chipMock.chip, times(2)).removeP2pIface("p2p0");
677         verify(p2pDestroyedListener2).onDestroyed();
678 
679         // Should now be able to request and get NAN
680         nanIface = validateInterfaceSequence(chipMock,
681                 true, // chipModeValid
682                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
683                 IfaceType.NAN, // ifaceTypeToCreate
684                 "nan0", // ifaceName
685                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
686                 null, // tearDownList
687                 nanDestroyedListener, // destroyedListener
688                 nanAvailListener // availableListener
689         );
690         collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
691 
692         // available callback verification
693         verify(staAvailListener).onAvailableForRequest();
694         verify(apAvailListener, times(4)).onAvailableForRequest();
695         verify(p2pAvailListener, times(3)).onAvailableForRequest();
696         verify(nanAvailListener).onAvailableForRequest();
697 
698         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
699                 staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener,
700                 nanDestroyedListener, nanAvailListener, p2pDestroyedListener2);
701     }
702 
703     /**
704      * Validate P2P and NAN interactions. Expect:
705      * - STA created
706      * - NAN created
707      * - When P2P requested:
708      *   - NAN torn down
709      *   - P2P created
710      * - NAN creation refused
711      * - When P2P destroyed:
712      *   - get nan available listener
713      *   - Can create NAN when requested
714      */
715     @Test
testP2pAndNanInteractions()716     public void testP2pAndNanInteractions() throws Exception {
717         BaselineChip chipMock = new BaselineChip();
718         chipMock.initialize();
719         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
720                 mManagerStatusListenerMock);
721         executeAndValidateInitializationSequence();
722         executeAndValidateStartupSequence();
723 
724         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
725                 HalDeviceManager.InterfaceDestroyedListener.class);
726         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
727                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
728 
729         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
730                 HalDeviceManager.InterfaceDestroyedListener.class);
731         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
732                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
733 
734         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
735                 HalDeviceManager.InterfaceDestroyedListener.class);
736         HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = null;
737 
738         // Request STA
739         IWifiIface staIface = validateInterfaceSequence(chipMock,
740                 false, // chipModeValid
741                 -1000, // chipModeId (only used if chipModeValid is true)
742                 IfaceType.STA, // ifaceTypeToCreate
743                 "sta0", // ifaceName
744                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
745                 null, // tearDownList
746                 staDestroyedListener, // destroyedListener
747                 staAvailListener // availableListener
748         );
749 
750         // Request NAN
751         IWifiIface nanIface = validateInterfaceSequence(chipMock,
752                 true, // chipModeValid
753                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
754                 IfaceType.NAN, // ifaceTypeToCreate
755                 "nan0", // ifaceName
756                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
757                 null, // tearDownList
758                 nanDestroyedListener, // destroyedListener
759                 nanAvailListener // availableListener
760         );
761 
762         // Request P2P
763         IWifiIface p2pIface = validateInterfaceSequence(chipMock,
764                 true, // chipModeValid
765                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
766                 IfaceType.P2P, // ifaceTypeToCreate
767                 "p2p0", // ifaceName
768                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
769                 new IWifiIface[]{nanIface}, // tearDownList
770                 p2pDestroyedListener, // destroyedListener
771                 p2pAvailListener, // availableListener
772                 nanDestroyedListener // destroyedInterfacesDestroyedListeners...
773         );
774 
775         // Request NAN: expect failure
776         nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
777         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
778                 mTestLooper.getLooper());
779         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
780 
781         // Destroy P2P interface
782         boolean status = mDut.removeIface(p2pIface);
783         mInOrder.verify(chipMock.chip).removeP2pIface("p2p0");
784         collector.checkThat("P2P removal success", status, equalTo(true));
785 
786         mTestLooper.dispatchAll();
787         verify(p2pDestroyedListener).onDestroyed();
788         verify(nanAvailListener).onAvailableForRequest();
789 
790         // Request NAN: expect success now
791         nanIface = validateInterfaceSequence(chipMock,
792                 true, // chipModeValid
793                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
794                 IfaceType.NAN, // ifaceTypeToCreate
795                 "nan0", // ifaceName
796                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
797                 null, // tearDownList
798                 nanDestroyedListener, // destroyedListener
799                 nanAvailListener // availableListener
800         );
801 
802         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
803                 nanDestroyedListener, nanAvailListener, p2pDestroyedListener);
804     }
805 
806     /**
807      * Validates that when (for some reason) the cache is out-of-sync with the actual chip status
808      * then Wi-Fi is shut-down.
809      */
810     @Test
testCacheMismatchError()811     public void testCacheMismatchError() throws Exception {
812         BaselineChip chipMock = new BaselineChip();
813         chipMock.initialize();
814         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
815                 mManagerStatusListenerMock);
816         executeAndValidateInitializationSequence();
817         executeAndValidateStartupSequence();
818 
819         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
820                 HalDeviceManager.InterfaceDestroyedListener.class);
821         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
822                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
823 
824         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
825                 HalDeviceManager.InterfaceDestroyedListener.class);
826         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
827                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
828 
829         // Request STA
830         IWifiIface staIface = validateInterfaceSequence(chipMock,
831                 false, // chipModeValid
832                 -1000, // chipModeId (only used if chipModeValid is true)
833                 IfaceType.STA, // ifaceTypeToCreate
834                 "sta0", // ifaceName
835                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
836                 null, // tearDownList
837                 staDestroyedListener, // destroyedListener
838                 staAvailListener // availableListener
839         );
840 
841         // Request NAN
842         IWifiIface nanIface = validateInterfaceSequence(chipMock,
843                 true, // chipModeValid
844                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
845                 IfaceType.NAN, // ifaceTypeToCreate
846                 "nan0", // ifaceName
847                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
848                 null, // tearDownList
849                 nanDestroyedListener, // destroyedListener
850                 nanAvailListener // availableListener
851         );
852 
853         // fiddle with the "chip" by removing the STA
854         chipMock.interfaceNames.get(IfaceType.STA).remove("sta0");
855 
856         // now try to request another NAN
857         nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
858         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
859                 mTestLooper.getLooper());
860         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
861 
862         // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
863         // registered (even if they seem out-of-sync to chip)
864         mTestLooper.dispatchAll();
865         verify(mWifiMock, times(2)).stop();
866         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
867         verify(staDestroyedListener).onDestroyed();
868         verify(nanDestroyedListener).onDestroyed();
869 
870         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
871                 nanDestroyedListener, nanAvailListener);
872     }
873 
874     /**
875      * Validates that trying to allocate a STA and then another STA fails. Only one STA at a time
876      * is permitted (by baseline chip).
877      */
878     @Test
testDuplicateStaRequests()879     public void testDuplicateStaRequests() throws Exception {
880         BaselineChip chipMock = new BaselineChip();
881         chipMock.initialize();
882         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
883                 mManagerStatusListenerMock);
884         executeAndValidateInitializationSequence();
885         executeAndValidateStartupSequence();
886 
887         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener1 = mock(
888                 HalDeviceManager.InterfaceDestroyedListener.class);
889         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener1 = mock(
890                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
891 
892         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock(
893                 HalDeviceManager.InterfaceDestroyedListener.class);
894 
895         // get STA interface
896         IWifiIface staIface1 = validateInterfaceSequence(chipMock,
897                 false, // chipModeValid
898                 -1000, // chipModeId (only used if chipModeValid is true)
899                 IfaceType.STA, // ifaceTypeToCreate
900                 "sta0", // ifaceName
901                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
902                 null, // tearDownList
903                 staDestroyedListener1, // destroyedListener
904                 staAvailListener1 // availableListener
905         );
906         collector.checkThat("STA created", staIface1, IsNull.notNullValue());
907 
908         // get STA interface again
909         IWifiIface staIface2 = mDut.createStaIface(staDestroyedListener2, mTestLooper.getLooper());
910         collector.checkThat("STA created", staIface2, IsNull.nullValue());
911 
912         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener1,
913                 staAvailListener1, staDestroyedListener2);
914     }
915 
916     /**
917      * Validates that a duplicate registration of the same InterfaceAvailableForRequestListener
918      * listener will result in a single callback.
919      *
920      * Also validates that get an immediate call on registration if available.
921      */
922     @Test
testDuplicateAvailableRegistrations()923     public void testDuplicateAvailableRegistrations() throws Exception {
924         BaselineChip chipMock = new BaselineChip();
925         chipMock.initialize();
926         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
927                 mManagerStatusListenerMock);
928         executeAndValidateInitializationSequence();
929         executeAndValidateStartupSequence();
930 
931         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
932                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
933 
934         // get STA interface
935         IWifiIface staIface = validateInterfaceSequence(chipMock,
936                 false, // chipModeValid
937                 -1000, // chipModeId (only used if chipModeValid is true)
938                 IfaceType.STA, // ifaceTypeToCreate
939                 "sta0", // ifaceName
940                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
941                 null, // tearDownList
942                 null, // destroyedListener
943                 null // availableListener
944         );
945         collector.checkThat("STA created", staIface, IsNull.notNullValue());
946 
947         // act: register the same listener twice
948         mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
949                 mTestLooper.getLooper());
950         mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
951                 mTestLooper.getLooper());
952         mTestLooper.dispatchAll();
953 
954         // remove STA interface -> should trigger callbacks
955         mDut.removeIface(staIface);
956         mTestLooper.dispatchAll();
957 
958         // verify: only a single trigger
959         verify(staAvailListener).onAvailableForRequest();
960 
961         verifyNoMoreInteractions(staAvailListener);
962     }
963 
964     /**
965      * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
966      */
967     @Test
testGetSupportedIfaceTypesAll()968     public void testGetSupportedIfaceTypesAll() throws Exception {
969         BaselineChip chipMock = new BaselineChip();
970         chipMock.initialize();
971         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
972                 mManagerStatusListenerMock);
973         executeAndValidateInitializationSequence();
974         executeAndValidateStartupSequence();
975 
976         // try API
977         Set<Integer> results = mDut.getSupportedIfaceTypes();
978 
979         // verify results
980         Set<Integer> correctResults = new HashSet<>();
981         correctResults.add(IfaceType.AP);
982         correctResults.add(IfaceType.STA);
983         correctResults.add(IfaceType.P2P);
984         correctResults.add(IfaceType.NAN);
985 
986         assertEquals(correctResults, results);
987     }
988 
989     /**
990      * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
991      */
992     @Test
testGetSupportedIfaceTypesOneChip()993     public void testGetSupportedIfaceTypesOneChip() throws Exception {
994         BaselineChip chipMock = new BaselineChip();
995         chipMock.initialize();
996         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
997                 mManagerStatusListenerMock);
998         executeAndValidateInitializationSequence();
999         executeAndValidateStartupSequence();
1000 
1001         // try API
1002         Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
1003 
1004         // verify results
1005         Set<Integer> correctResults = new HashSet<>();
1006         correctResults.add(IfaceType.AP);
1007         correctResults.add(IfaceType.STA);
1008         correctResults.add(IfaceType.P2P);
1009         correctResults.add(IfaceType.NAN);
1010 
1011         assertEquals(correctResults, results);
1012     }
1013 
1014     /**
1015      * Validate that when no chip info is found an empty list is returned.
1016      */
1017     @Test
testGetSupportedIfaceTypesError()1018     public void testGetSupportedIfaceTypesError() throws Exception {
1019         // try API
1020         Set<Integer> results = mDut.getSupportedIfaceTypes();
1021 
1022         // verify results
1023         assertEquals(0, results.size());
1024     }
1025 
1026     /**
1027      * Test start HAL can retry upon failure.
1028      */
1029     @Test
testStartHalRetryUponNotAvailableFailure()1030     public void testStartHalRetryUponNotAvailableFailure() throws Exception {
1031         // Override the stubbing for mWifiMock in before().
1032         when(mWifiMock.start())
1033             .thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE))
1034             .thenReturn(mStatusOk);
1035 
1036         BaselineChip chipMock = new BaselineChip();
1037         chipMock.initialize();
1038         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
1039                 mManagerStatusListenerMock);
1040         executeAndValidateInitializationSequence();
1041         executeAndValidateStartupSequence(2, true);
1042     }
1043 
1044     /**
1045      * Test start HAL fails after multiple retry failures.
1046      */
1047     @Test
testStartHalRetryFailUponMultipleNotAvailableFailures()1048     public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception {
1049         // Override the stubbing for mWifiMock in before().
1050         when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE));
1051 
1052         BaselineChip chipMock = new BaselineChip();
1053         chipMock.initialize();
1054         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
1055         executeAndValidateInitializationSequence();
1056         executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false);
1057     }
1058 
1059     /**
1060      * Test start HAL fails after multiple retry failures.
1061      */
1062     @Test
testStartHalRetryFailUponTrueFailure()1063     public void testStartHalRetryFailUponTrueFailure() throws Exception {
1064         // Override the stubbing for mWifiMock in before().
1065         when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN));
1066 
1067         BaselineChip chipMock = new BaselineChip();
1068         chipMock.initialize();
1069         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
1070         executeAndValidateInitializationSequence();
1071         executeAndValidateStartupSequence(1, false);
1072     }
1073 
1074     /**
1075      * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
1076      * the VINTF.
1077      */
1078     @Test
testIsSupportedTrue()1079     public void testIsSupportedTrue() throws Exception {
1080         mInOrder = inOrder(mServiceManagerMock, mWifiMock);
1081         executeAndValidateInitializationSequence();
1082         assertTrue(mDut.isSupported());
1083     }
1084 
1085     /**
1086      * Validate that isSupported() returns false when IServiceManager does not find the vendor HAL
1087      * daemon in the VINTF.
1088      */
1089     @Test
testIsSupportedFalse()1090     public void testIsSupportedFalse() throws Exception {
1091         when(mServiceManagerMock.getTransport(
1092                 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
1093                 .thenReturn(IServiceManager.Transport.EMPTY);
1094         mInOrder = inOrder(mServiceManagerMock, mWifiMock);
1095         executeAndValidateInitializationSequence(false);
1096         assertFalse(mDut.isSupported());
1097     }
1098 
1099     // utilities
dumpDut(String prefix)1100     private void dumpDut(String prefix) {
1101         StringWriter sw = new StringWriter();
1102         mDut.dump(null, new PrintWriter(sw), null);
1103         Log.e("HalDeviceManager", prefix + sw.toString());
1104     }
1105 
executeAndValidateInitializationSequence()1106     private void executeAndValidateInitializationSequence() throws Exception {
1107         executeAndValidateInitializationSequence(true);
1108     }
1109 
executeAndValidateInitializationSequence(boolean isSupported)1110     private void executeAndValidateInitializationSequence(boolean isSupported) throws Exception {
1111         // act:
1112         mDut.initialize();
1113 
1114         // verify: service manager initialization sequence
1115         mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
1116                 anyLong());
1117         mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
1118                 eq(""), mServiceNotificationCaptor.capture());
1119 
1120         // The service should already be up at this point.
1121         mInOrder.verify(mServiceManagerMock).getTransport(eq(IWifi.kInterfaceName),
1122                 eq(HalDeviceManager.HAL_INSTANCE_NAME));
1123 
1124         // verify: wifi initialization sequence if vendor HAL is supported.
1125         if (isSupported) {
1126             mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
1127             mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
1128             // verify: onStop called as a part of initialize.
1129             mInOrder.verify(mWifiMock).stop();
1130             collector.checkThat("isReady is true", mDut.isReady(), equalTo(true));
1131         } else {
1132             collector.checkThat("isReady is false", mDut.isReady(), equalTo(false));
1133         }
1134     }
1135 
executeAndValidateStartupSequence()1136     private void executeAndValidateStartupSequence()throws Exception {
1137         executeAndValidateStartupSequence(1, true);
1138     }
1139 
executeAndValidateStartupSequence(int numAttempts, boolean success)1140     private void executeAndValidateStartupSequence(int numAttempts, boolean success)
1141             throws Exception {
1142         // act: register listener & start Wi-Fi
1143         mDut.registerStatusListener(mManagerStatusListenerMock, mTestLooper.getLooper());
1144         collector.checkThat(mDut.start(), equalTo(success));
1145 
1146         // verify
1147         mInOrder.verify(mWifiMock, times(numAttempts)).start();
1148 
1149         if (success) {
1150             // act: trigger onStart callback of IWifiEventCallback
1151             mWifiEventCallbackCaptor.getValue().onStart();
1152             mTestLooper.dispatchAll();
1153 
1154             // verify: onStart called on registered listener
1155             mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
1156         }
1157     }
1158 
validateInterfaceSequence(ChipMockBase chipMock, boolean chipModeValid, int chipModeId, int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList, HalDeviceManager.InterfaceDestroyedListener destroyedListener, HalDeviceManager.InterfaceAvailableForRequestListener availableListener, HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners)1159     private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
1160             boolean chipModeValid, int chipModeId,
1161             int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList,
1162             HalDeviceManager.InterfaceDestroyedListener destroyedListener,
1163             HalDeviceManager.InterfaceAvailableForRequestListener availableListener,
1164             HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners)
1165             throws Exception {
1166         // configure chip mode response
1167         chipMock.chipModeValid = chipModeValid;
1168         chipMock.chipModeId = chipModeId;
1169 
1170         IWifiIface iface = null;
1171 
1172         // configure: interface to be created
1173         // act: request the interface
1174         switch (ifaceTypeToCreate) {
1175             case IfaceType.STA:
1176                 iface = mock(IWifiStaIface.class);
1177                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
1178                         any(IWifiIface.getNameCallback.class));
1179                 doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
1180                         any(IWifiIface.getTypeCallback.class));
1181                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
1182                         chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
1183 
1184                 mDut.createStaIface(destroyedListener, mTestLooper.getLooper());
1185                 break;
1186             case IfaceType.AP:
1187                 iface = mock(IWifiApIface.class);
1188                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
1189                         any(IWifiIface.getNameCallback.class));
1190                 doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
1191                         any(IWifiIface.getTypeCallback.class));
1192                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
1193                         chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
1194 
1195                 mDut.createApIface(destroyedListener, mTestLooper.getLooper());
1196                 break;
1197             case IfaceType.P2P:
1198                 iface = mock(IWifiP2pIface.class);
1199                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
1200                         any(IWifiIface.getNameCallback.class));
1201                 doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
1202                         any(IWifiIface.getTypeCallback.class));
1203                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
1204                         chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
1205 
1206                 mDut.createP2pIface(destroyedListener, mTestLooper.getLooper());
1207                 break;
1208             case IfaceType.NAN:
1209                 iface = mock(IWifiNanIface.class);
1210                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
1211                         any(IWifiIface.getNameCallback.class));
1212                 doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
1213                         any(IWifiIface.getTypeCallback.class));
1214                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
1215                         chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
1216 
1217                 mDut.createNanIface(destroyedListener, mTestLooper.getLooper());
1218                 break;
1219         }
1220         if (availableListener != null) {
1221             mDut.registerInterfaceAvailableForRequestListener(ifaceTypeToCreate, availableListener,
1222                     mTestLooper.getLooper());
1223         }
1224 
1225         // validate: optional tear down of interfaces
1226         if (tearDownList != null) {
1227             for (IWifiIface tearDownIface: tearDownList) {
1228                 switch (getType(tearDownIface)) {
1229                     case IfaceType.STA:
1230                         mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
1231                         break;
1232                     case IfaceType.AP:
1233                         mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
1234                         break;
1235                     case IfaceType.P2P:
1236                         mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
1237                         break;
1238                     case IfaceType.NAN:
1239                         mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
1240                         break;
1241                 }
1242             }
1243         }
1244 
1245         // validate: optional switch to the requested mode
1246         if (!chipModeValid || chipModeId != finalChipMode) {
1247             mInOrder.verify(chipMock.chip).configureChip(finalChipMode);
1248         } else {
1249             mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt());
1250         }
1251 
1252         // validate: create interface
1253         switch (ifaceTypeToCreate) {
1254             case IfaceType.STA:
1255                 mInOrder.verify(chipMock.chip).createStaIface(
1256                         any(IWifiChip.createStaIfaceCallback.class));
1257                 break;
1258             case IfaceType.AP:
1259                 mInOrder.verify(chipMock.chip).createApIface(
1260                         any(IWifiChip.createApIfaceCallback.class));
1261                 break;
1262             case IfaceType.P2P:
1263                 mInOrder.verify(chipMock.chip).createP2pIface(
1264                         any(IWifiChip.createP2pIfaceCallback.class));
1265                 break;
1266             case IfaceType.NAN:
1267                 mInOrder.verify(chipMock.chip).createNanIface(
1268                         any(IWifiChip.createNanIfaceCallback.class));
1269                 break;
1270         }
1271 
1272         // verify: callbacks on deleted interfaces
1273         mTestLooper.dispatchAll();
1274         for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) {
1275             verify(destroyedInterfacesDestroyedListeners[i]).onDestroyed();
1276         }
1277 
1278         return iface;
1279     }
1280 
getType(IWifiIface iface)1281     private int getType(IWifiIface iface) throws Exception {
1282         Mutable<Integer> typeResp = new Mutable<>();
1283         iface.getType((WifiStatus status, int type) -> {
1284             typeResp.value = type;
1285         });
1286         return typeResp.value;
1287     }
1288 
getName(IWifiIface iface)1289     private String getName(IWifiIface iface) throws Exception {
1290         Mutable<String> nameResp = new Mutable<>();
1291         iface.getName((WifiStatus status, String name) -> {
1292             nameResp.value = name;
1293         });
1294         return nameResp.value;
1295     }
1296 
getStatus(int code)1297     private WifiStatus getStatus(int code) {
1298         WifiStatus status = new WifiStatus();
1299         status.code = code;
1300         return status;
1301     }
1302 
1303     private static class Mutable<E> {
1304         public E value;
1305 
Mutable()1306         Mutable() {
1307             value = null;
1308         }
1309 
Mutable(E value)1310         Mutable(E value) {
1311             this.value = value;
1312         }
1313     }
1314 
1315     // Answer objects
1316     private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
1317         private WifiStatus mStatus;
1318         private ArrayList<Integer> mChipIds;
1319 
GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds)1320         GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
1321             mStatus = status;
1322             mChipIds = chipIds;
1323         }
1324 
answer(IWifi.getChipIdsCallback cb)1325         public void answer(IWifi.getChipIdsCallback cb) {
1326             cb.onValues(mStatus, mChipIds);
1327         }
1328     }
1329 
1330     private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
1331         private WifiStatus mStatus;
1332         private IWifiChip mChip;
1333 
GetChipAnswer(WifiStatus status, IWifiChip chip)1334         GetChipAnswer(WifiStatus status, IWifiChip chip) {
1335             mStatus = status;
1336             mChip = chip;
1337         }
1338 
answer(int chipId, IWifi.getChipCallback cb)1339         public void answer(int chipId, IWifi.getChipCallback cb) {
1340             cb.onValues(mStatus, mChip);
1341         }
1342     }
1343 
1344     private class GetIdAnswer extends MockAnswerUtil.AnswerWithArguments {
1345         private ChipMockBase mChipMockBase;
1346 
GetIdAnswer(ChipMockBase chipMockBase)1347         GetIdAnswer(ChipMockBase chipMockBase) {
1348             mChipMockBase = chipMockBase;
1349         }
1350 
answer(IWifiChip.getIdCallback cb)1351         public void answer(IWifiChip.getIdCallback cb) {
1352             cb.onValues(mStatusOk, mChipMockBase.chipId);
1353         }
1354     }
1355 
1356     private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments {
1357         private ChipMockBase mChipMockBase;
1358 
GetAvailableModesAnswer(ChipMockBase chipMockBase)1359         GetAvailableModesAnswer(ChipMockBase chipMockBase) {
1360             mChipMockBase = chipMockBase;
1361         }
1362 
answer(IWifiChip.getAvailableModesCallback cb)1363         public void answer(IWifiChip.getAvailableModesCallback cb) {
1364             cb.onValues(mStatusOk, mChipMockBase.availableModes);
1365         }
1366     }
1367 
1368     private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments {
1369         private ChipMockBase mChipMockBase;
1370 
GetModeAnswer(ChipMockBase chipMockBase)1371         GetModeAnswer(ChipMockBase chipMockBase) {
1372             mChipMockBase = chipMockBase;
1373         }
1374 
answer(IWifiChip.getModeCallback cb)1375         public void answer(IWifiChip.getModeCallback cb) {
1376             cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
1377                     : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
1378         }
1379     }
1380 
1381     private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments {
1382         private ChipMockBase mChipMockBase;
1383 
ConfigureChipAnswer(ChipMockBase chipMockBase)1384         ConfigureChipAnswer(ChipMockBase chipMockBase) {
1385             mChipMockBase = chipMockBase;
1386         }
1387 
answer(int chipMode)1388         public WifiStatus answer(int chipMode) {
1389             mChipMockBase.chipModeId = chipMode;
1390             return mStatusOk;
1391         }
1392     }
1393 
1394     private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
1395         private ChipMockBase mChipMockBase;
1396 
GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase)1397         GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
1398             mChipMockBase = chipMockBase;
1399         }
1400 
answer(IWifiChip.getStaIfaceNamesCallback cb)1401         public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
1402             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
1403         }
1404 
answer(IWifiChip.getApIfaceNamesCallback cb)1405         public void answer(IWifiChip.getApIfaceNamesCallback cb) {
1406             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
1407         }
1408 
answer(IWifiChip.getP2pIfaceNamesCallback cb)1409         public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
1410             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
1411         }
1412 
answer(IWifiChip.getNanIfaceNamesCallback cb)1413         public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
1414             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
1415         }
1416     }
1417 
1418     private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
1419         private ChipMockBase mChipMockBase;
1420 
GetXxxIfaceAnswer(ChipMockBase chipMockBase)1421         GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
1422             mChipMockBase = chipMockBase;
1423         }
1424 
answer(String name, IWifiChip.getStaIfaceCallback cb)1425         public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
1426             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
1427             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
1428         }
1429 
answer(String name, IWifiChip.getApIfaceCallback cb)1430         public void answer(String name, IWifiChip.getApIfaceCallback cb) {
1431             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
1432             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
1433         }
1434 
answer(String name, IWifiChip.getP2pIfaceCallback cb)1435         public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
1436             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
1437             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
1438         }
1439 
answer(String name, IWifiChip.getNanIfaceCallback cb)1440         public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
1441             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
1442             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
1443         }
1444     }
1445 
1446     private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
1447         private ChipMockBase mChipMockBase;
1448         private WifiStatus mStatus;
1449         private IWifiIface mWifiIface;
1450 
CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface)1451         CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
1452             mChipMockBase = chipMockBase;
1453             mStatus = status;
1454             mWifiIface = wifiIface;
1455         }
1456 
addInterfaceInfo(int type)1457         private void addInterfaceInfo(int type) {
1458             if (mStatus.code == WifiStatusCode.SUCCESS) {
1459                 try {
1460                     mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
1461                     mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
1462                 } catch (Exception e) {
1463                     // do nothing
1464                 }
1465             }
1466         }
1467 
answer(IWifiChip.createStaIfaceCallback cb)1468         public void answer(IWifiChip.createStaIfaceCallback cb) {
1469             cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
1470             addInterfaceInfo(IfaceType.STA);
1471         }
1472 
answer(IWifiChip.createApIfaceCallback cb)1473         public void answer(IWifiChip.createApIfaceCallback cb) {
1474             cb.onValues(mStatus, (IWifiApIface) mWifiIface);
1475             addInterfaceInfo(IfaceType.AP);
1476         }
1477 
answer(IWifiChip.createP2pIfaceCallback cb)1478         public void answer(IWifiChip.createP2pIfaceCallback cb) {
1479             cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
1480             addInterfaceInfo(IfaceType.P2P);
1481         }
1482 
answer(IWifiChip.createNanIfaceCallback cb)1483         public void answer(IWifiChip.createNanIfaceCallback cb) {
1484             cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
1485             addInterfaceInfo(IfaceType.NAN);
1486         }
1487     }
1488 
1489     private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
1490         private ChipMockBase mChipMockBase;
1491         private int mType;
1492 
RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type)1493         RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
1494             mChipMockBase = chipMockBase;
1495             mType = type;
1496         }
1497 
removeIface(int type, String ifname)1498         private WifiStatus removeIface(int type, String ifname) {
1499             try {
1500                 if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
1501                     return mStatusFail;
1502                 }
1503                 if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
1504                     return mStatusFail;
1505                 }
1506             } catch (Exception e) {
1507                 return mStatusFail;
1508             }
1509             return mStatusOk;
1510         }
1511 
answer(String ifname)1512         public WifiStatus answer(String ifname) {
1513             return removeIface(mType, ifname);
1514         }
1515     }
1516 
1517     private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments {
1518         private String mName;
1519 
GetNameAnswer(String name)1520         GetNameAnswer(String name) {
1521             mName = name;
1522         }
1523 
answer(IWifiIface.getNameCallback cb)1524         public void answer(IWifiIface.getNameCallback cb) {
1525             cb.onValues(mStatusOk, mName);
1526         }
1527     }
1528 
1529     private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
1530         private int mType;
1531 
GetTypeAnswer(int type)1532         GetTypeAnswer(int type) {
1533             mType = type;
1534         }
1535 
answer(IWifiIface.getTypeCallback cb)1536         public void answer(IWifiIface.getTypeCallback cb) {
1537             cb.onValues(mStatusOk, mType);
1538         }
1539     }
1540 
1541     // chip configuration
1542 
1543     private class ChipMockBase {
1544         public IWifiChip chip;
1545         public int chipId;
1546         public boolean chipModeValid = false;
1547         public int chipModeId = -1000;
1548         public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
1549         public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
1550 
1551         public ArrayList<IWifiChip.ChipMode> availableModes;
1552 
initialize()1553         void initialize() throws Exception {
1554             chip = mock(IWifiChip.class);
1555 
1556             interfaceNames.put(IfaceType.STA, new ArrayList<>());
1557             interfaceNames.put(IfaceType.AP, new ArrayList<>());
1558             interfaceNames.put(IfaceType.P2P, new ArrayList<>());
1559             interfaceNames.put(IfaceType.NAN, new ArrayList<>());
1560 
1561             interfacesByName.put(IfaceType.STA, new HashMap<>());
1562             interfacesByName.put(IfaceType.AP, new HashMap<>());
1563             interfacesByName.put(IfaceType.P2P, new HashMap<>());
1564             interfacesByName.put(IfaceType.NAN, new HashMap<>());
1565 
1566             when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
1567                     mStatusOk);
1568             when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
1569             doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class));
1570             doAnswer(new GetModeAnswer(this)).when(chip).getMode(
1571                     any(IWifiChip.getModeCallback.class));
1572             GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
1573             doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
1574                     any(IWifiChip.getStaIfaceNamesCallback.class));
1575             doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
1576                     any(IWifiChip.getApIfaceNamesCallback.class));
1577             doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
1578                     any(IWifiChip.getP2pIfaceNamesCallback.class));
1579             doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
1580                     any(IWifiChip.getNanIfaceNamesCallback.class));
1581             GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
1582             doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
1583                     any(IWifiChip.getStaIfaceCallback.class));
1584             doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
1585                     any(IWifiChip.getApIfaceCallback.class));
1586             doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
1587                     any(IWifiChip.getP2pIfaceCallback.class));
1588             doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
1589                     any(IWifiChip.getNanIfaceCallback.class));
1590             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
1591                     anyString());
1592             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
1593                     anyString());
1594             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
1595                     anyString());
1596             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
1597                     anyString());
1598         }
1599     }
1600 
1601     // emulate baseline/legacy config:
1602     // mode: STA + NAN || P2P
1603     // mode: NAN
1604     private class BaselineChip extends ChipMockBase {
1605         static final int STA_CHIP_MODE_ID = 0;
1606         static final int AP_CHIP_MODE_ID = 1;
1607 
initialize()1608         void initialize() throws Exception {
1609             super.initialize();
1610 
1611             // chip Id configuration
1612             ArrayList<Integer> chipIds;
1613             chipId = 10;
1614             chipIds = new ArrayList<>();
1615             chipIds.add(chipId);
1616             doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
1617                     any(IWifi.getChipIdsCallback.class));
1618 
1619             doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
1620                     any(IWifi.getChipCallback.class));
1621 
1622             // initialize dummy chip modes
1623             IWifiChip.ChipMode cm;
1624             IWifiChip.ChipIfaceCombination cic;
1625             IWifiChip.ChipIfaceCombinationLimit cicl;
1626 
1627             //   Mode 0: 1xSTA + 1x{P2P,NAN}
1628             //   Mode 1: 1xAP
1629             availableModes = new ArrayList<>();
1630             cm = new IWifiChip.ChipMode();
1631             cm.id = STA_CHIP_MODE_ID;
1632 
1633             cic = new IWifiChip.ChipIfaceCombination();
1634 
1635             cicl = new IWifiChip.ChipIfaceCombinationLimit();
1636             cicl.maxIfaces = 1;
1637             cicl.types.add(IfaceType.STA);
1638             cic.limits.add(cicl);
1639 
1640             cicl = new IWifiChip.ChipIfaceCombinationLimit();
1641             cicl.maxIfaces = 1;
1642             cicl.types.add(IfaceType.P2P);
1643             cicl.types.add(IfaceType.NAN);
1644             cic.limits.add(cicl);
1645             cm.availableCombinations.add(cic);
1646             availableModes.add(cm);
1647 
1648             cm = new IWifiChip.ChipMode();
1649             cm.id = AP_CHIP_MODE_ID;
1650             cic = new IWifiChip.ChipIfaceCombination();
1651             cicl = new IWifiChip.ChipIfaceCombinationLimit();
1652             cicl.maxIfaces = 1;
1653             cicl.types.add(IfaceType.AP);
1654             cic.limits.add(cicl);
1655             cm.availableCombinations.add(cic);
1656             availableModes.add(cm);
1657 
1658             doAnswer(new GetAvailableModesAnswer(this)).when(chip)
1659                     .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
1660         }
1661     }
1662 }
1663