WifiVendorHalTest.java revision 4f2049a015722cae0f0169379d499d5d4fc98e30
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 android.app.test.MockAnswerUtil.AnswerWithArguments;
20import android.hardware.wifi.V1_0.IWifiApIface;
21import android.hardware.wifi.V1_0.IWifiChip;
22import android.hardware.wifi.V1_0.IWifiIface;
23import android.hardware.wifi.V1_0.IWifiRttController;
24import android.hardware.wifi.V1_0.IWifiStaIface;
25import android.hardware.wifi.V1_0.WifiStatus;
26import android.hardware.wifi.V1_0.WifiStatusCode;
27
28import static org.junit.Assert.*;
29import static org.mockito.Mockito.*;
30
31import android.os.HandlerThread;
32import android.os.Looper;
33
34import org.junit.Assert;
35import org.junit.Before;
36import org.junit.Test;
37import org.mockito.ArgumentCaptor;
38import org.mockito.Mock;
39import org.mockito.MockitoAnnotations;
40
41
42/**
43 * Unit tests for {@link com.android.server.wifi.WifiVendorHal}.
44 */
45public class WifiVendorHalTest {
46
47    WifiVendorHal mWifiVendorHal;
48    private WifiStatus mWifiStatusSuccess;
49    private WifiStatus mWifiStatusFailure;
50    @Mock
51    private HalDeviceManager mHalDeviceManager;
52    @Mock
53    private HandlerThread mWifiStateMachineHandlerThread;
54    @Mock
55    private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
56    @Mock
57    private IWifiApIface mIWifiApIface;
58    @Mock
59    private IWifiChip mIWifiChip;
60    @Mock
61    private IWifiStaIface mIWifiStaIface;
62    @Mock
63    private IWifiRttController mIWifiRttController;
64
65    /**
66     * Sets up for unit test
67     */
68    @Before
69    public void setUp() throws Exception {
70        MockitoAnnotations.initMocks(this);
71        mWifiStatusSuccess = new WifiStatus();
72        mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
73        mWifiStatusFailure = new WifiStatus();
74        mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN;
75        mWifiStatusFailure.description = "I don't even know what a Mock Turtle is.";
76        when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess);
77
78
79        // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in
80        // individual tests, if needed.
81        doAnswer(new AnswerWithArguments() {
82            public boolean answer() {
83                when(mHalDeviceManager.isReady()).thenReturn(true);
84                when(mHalDeviceManager.isStarted()).thenReturn(true);
85                mHalDeviceManagerStatusCallbacks.onStatusChanged();
86                return true;
87            }
88        }).when(mHalDeviceManager).start();
89
90        doAnswer(new AnswerWithArguments() {
91            public void answer() {
92                when(mHalDeviceManager.isReady()).thenReturn(true);
93                when(mHalDeviceManager.isStarted()).thenReturn(false);
94                mHalDeviceManagerStatusCallbacks.onStatusChanged();
95            }
96        }).when(mHalDeviceManager).stop();
97        when(mHalDeviceManager.createStaIface(eq(null), eq(null)))
98                .thenReturn(mIWifiStaIface);
99        when(mHalDeviceManager.createApIface(eq(null), eq(null)))
100                .thenReturn(mIWifiApIface);
101        when(mHalDeviceManager.getChip(any(IWifiIface.class)))
102                .thenReturn(mIWifiChip);
103        when(mHalDeviceManager.createRttController(any(IWifiIface.class)))
104                .thenReturn(mIWifiRttController);
105
106        // Create the vendor HAL object under test.
107        mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread);
108
109        // Initialize the vendor HAL to capture the registered callback.
110        mWifiVendorHal.initialize();
111        ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> callbackCaptor =
112                ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class);
113        verify(mHalDeviceManager).registerStatusListener(
114                callbackCaptor.capture(), any(Looper.class));
115        mHalDeviceManagerStatusCallbacks = callbackCaptor.getValue();
116    }
117
118    /**
119     * Test that parsing a typical colon-delimited MAC adddress works
120     */
121    @Test
122    public void testTypicalHexParse() throws Exception {
123        byte[] sixBytes = new byte[6];
124        mWifiVendorHal.parseUnquotedMacStrToByteArray("61:52:43:34:25:16", sixBytes);
125        Assert.assertArrayEquals(new byte[]{0x61, 0x52, 0x43, 0x34, 0x25, 0x16}, sixBytes);
126    }
127
128    /**
129     * Tests the successful starting of HAL in STA mode using
130     * {@link WifiVendorHal#startVendorHal(boolean)}.
131     */
132    @Test
133    public void testStartHalSuccessInStaMode() {
134        assertTrue(mWifiVendorHal.startVendorHal(true));
135        assertTrue(mWifiVendorHal.isHalStarted());
136
137        verify(mHalDeviceManager).start();
138        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
139        verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
140        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
141        verify(mHalDeviceManager).isReady();
142        verify(mHalDeviceManager).isStarted();
143
144        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
145    }
146
147    /**
148     * Tests the successful starting of HAL in AP mode using
149     * {@link WifiVendorHal#startVendorHal(boolean)}.
150     */
151    @Test
152    public void testStartHalSuccessInApMode() {
153        assertTrue(mWifiVendorHal.startVendorHal(false));
154        assertTrue(mWifiVendorHal.isHalStarted());
155
156        verify(mHalDeviceManager).start();
157        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
158        verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
159        verify(mHalDeviceManager).isReady();
160        verify(mHalDeviceManager).isStarted();
161
162        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
163        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
164    }
165
166    /**
167     * Tests the failure to start HAL in STA mode using
168     * {@link WifiVendorHal#startVendorHal(boolean)}.
169     */
170    @Test
171    public void testStartHalFailureInStaMode() {
172        // No callbacks are invoked in this case since the start itself failed. So, override
173        // default AnswerWithArguments that we setup.
174        doAnswer(new AnswerWithArguments() {
175            public boolean answer() {
176                return false;
177            }
178        }).when(mHalDeviceManager).start();
179        assertFalse(mWifiVendorHal.startVendorHal(true));
180        assertFalse(mWifiVendorHal.isHalStarted());
181
182        verify(mHalDeviceManager).start();
183
184        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
185        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
186        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
187        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
188    }
189
190    /**
191     * Tests the failure to start HAL in STA mode using
192     * {@link WifiVendorHal#startVendorHal(boolean)}.
193     */
194    @Test
195    public void testStartHalFailureInIfaceCreationInStaMode() {
196        when(mHalDeviceManager.createStaIface(eq(null), eq(null))).thenReturn(null);
197        assertFalse(mWifiVendorHal.startVendorHal(true));
198        assertFalse(mWifiVendorHal.isHalStarted());
199
200        verify(mHalDeviceManager).start();
201        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
202        verify(mHalDeviceManager).stop();
203
204        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
205        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
206        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
207    }
208
209    /**
210     * Tests the failure to start HAL in STA mode using
211     * {@link WifiVendorHal#startVendorHal(boolean)}.
212     */
213    @Test
214    public void testStartHalFailureInRttControllerCreationInStaMode() {
215        when(mHalDeviceManager.createRttController(any(IWifiIface.class))).thenReturn(null);
216        assertFalse(mWifiVendorHal.startVendorHal(true));
217        assertFalse(mWifiVendorHal.isHalStarted());
218
219        verify(mHalDeviceManager).start();
220        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
221        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
222        verify(mHalDeviceManager).stop();
223
224        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
225        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
226    }
227
228    /**
229     * Tests the failure to start HAL in STA mode using
230     * {@link WifiVendorHal#startVendorHal(boolean)}.
231     */
232    @Test
233    public void testStartHalFailureInChipGetInStaMode() {
234        when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null);
235        assertFalse(mWifiVendorHal.startVendorHal(true));
236        assertFalse(mWifiVendorHal.isHalStarted());
237
238        verify(mHalDeviceManager).start();
239        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
240        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
241        verify(mHalDeviceManager).getChip(any(IWifiIface.class));
242        verify(mHalDeviceManager).stop();
243
244        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
245    }
246
247    /**
248     * Tests the failure to start HAL in STA mode using
249     * {@link WifiVendorHal#startVendorHal(boolean)}.
250     */
251    @Test
252    public void testStartHalFailureInApMode() {
253        when(mHalDeviceManager.createApIface(eq(null), eq(null))).thenReturn(null);
254        assertFalse(mWifiVendorHal.startVendorHal(false));
255        assertFalse(mWifiVendorHal.isHalStarted());
256
257        verify(mHalDeviceManager).start();
258        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
259        verify(mHalDeviceManager).stop();
260
261        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
262        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
263        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
264    }
265
266    /**
267     * Tests the stopping of HAL in STA mode using
268     * {@link WifiVendorHal#stopVendorHal()}.
269     */
270    @Test
271    public void testStopHalInStaMode() {
272        assertTrue(mWifiVendorHal.startVendorHal(true));
273        assertTrue(mWifiVendorHal.isHalStarted());
274
275        mWifiVendorHal.stopVendorHal();
276        assertFalse(mWifiVendorHal.isHalStarted());
277
278        verify(mHalDeviceManager).start();
279        verify(mHalDeviceManager).stop();
280        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
281        verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
282        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
283        verify(mHalDeviceManager, times(2)).isReady();
284        verify(mHalDeviceManager, times(2)).isStarted();
285
286        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
287    }
288
289    /**
290     * Tests the stopping of HAL in AP mode using
291     * {@link WifiVendorHal#stopVendorHal()}.
292     */
293    @Test
294    public void testStopHalInApMode() {
295        assertTrue(mWifiVendorHal.startVendorHal(false));
296        assertTrue(mWifiVendorHal.isHalStarted());
297
298        mWifiVendorHal.stopVendorHal();
299        assertFalse(mWifiVendorHal.isHalStarted());
300
301        verify(mHalDeviceManager).start();
302        verify(mHalDeviceManager).stop();
303        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
304        verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
305        verify(mHalDeviceManager, times(2)).isReady();
306        verify(mHalDeviceManager, times(2)).isStarted();
307
308        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
309        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
310    }
311
312    /**
313     * Test enablement of link layer stats after startup
314     * <p>
315     * Request link layer stats before HAL start
316     * - should not make it to the HAL layer
317     * Start the HAL in STA mode
318     * Request link layer stats twice more
319     * - enable request should make it to the HAL layer
320     * - HAL layer should have been called to make the requests (i.e., two calls total)
321     */
322    @Test
323    public void testLinkLayerStatsEnableAfterStartup() throws Exception {
324        doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
325
326        assertNull(mWifiVendorHal.getWifiLinkLayerStats());
327        assertTrue(mWifiVendorHal.startVendorHalSta());
328        assertTrue(mWifiVendorHal.isHalStarted());
329
330        verify(mHalDeviceManager).start();
331        mWifiVendorHal.getWifiLinkLayerStats();
332        mWifiVendorHal.getWifiLinkLayerStats();
333        verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug
334        verify(mIWifiStaIface, times(2)).getLinkLayerStats(any());
335    }
336
337    /**
338     * Test that link layer stats are not enabled and harmless in AP mode
339     * <p>
340     * Start the HAL in AP mode
341     * - stats should not be enabled
342     * Request link layer stats
343     * - HAL layer should have been called to make the request
344     */
345    @Test
346    public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception {
347        doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
348
349        assertTrue(mWifiVendorHal.startVendorHalAp());
350        assertTrue(mWifiVendorHal.isHalStarted());
351        assertNull(mWifiVendorHal.getWifiLinkLayerStats());
352
353        verify(mHalDeviceManager).start();
354
355        verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false);
356        verify(mIWifiStaIface, never()).getLinkLayerStats(any());
357    }
358
359    // TODO(b/34900534) add test for correct MOVE CORRESPONDING of fields
360
361}
362