SupplicantP2pIfaceCallbackTest.java revision 7f7b374b3e75a929ab0d46426daf9a5e92c2d85b
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 */
16package com.android.server.wifi.p2p;
17
18import static org.junit.Assert.*;
19import static org.mockito.Matchers.*;
20import static org.mockito.Mockito.doAnswer;
21import static org.mockito.Mockito.doThrow;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.times;
25import static org.mockito.Mockito.verify;
26import static org.mockito.Mockito.when;
27
28import android.app.test.MockAnswerUtil.AnswerWithArguments;
29import android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIfaceCallback;
30import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
31import android.net.wifi.WpsInfo;
32import android.net.wifi.p2p.WifiP2pConfig;
33import android.net.wifi.p2p.WifiP2pDevice;
34import android.net.wifi.p2p.WifiP2pGroup;
35import android.net.wifi.p2p.WifiP2pProvDiscEvent;
36import android.net.wifi.p2p.WifiP2pWfdInfo;
37
38import org.junit.Assert.*;
39import org.junit.Before;
40import org.junit.Test;
41import org.mockito.ArgumentCaptor;
42import org.mockito.Mock;
43import org.mockito.MockitoAnnotations;
44import org.mockito.stubbing.Answer;
45
46import java.util.ArrayList;
47import java.util.HashSet;
48
49/**
50 * Unit tests for SupplicantP2pIfaceCallback
51 */
52public class SupplicantP2pIfaceCallbackTest {
53    private static final String TAG = "SupplicantP2pIfaceCallbackTest";
54
55    private String mIface = "test_p2p0";
56    private WifiP2pMonitor mMonitor;
57    private SupplicantP2pIfaceCallback mDut;
58
59    private byte[] mDeviceAddressInvalid1 = { 0x00 };
60    private byte[] mDeviceAddressInvalid2 = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
61    private byte[] mDeviceAddress1Bytes = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
62    private String mDeviceAddress1String = "00:11:22:33:44:55";
63    private byte[] mDeviceAddress2Bytes = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56 };
64    private String mDeviceAddress2String = "01:12:23:34:45:56";
65    private byte[] mDeviceInfoBytes = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
66    private static final byte[] DEVICE_ADDRESS = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
67
68    private class SupplicantP2pIfaceCallbackSpy extends SupplicantP2pIfaceCallback {
69        SupplicantP2pIfaceCallbackSpy(String iface, WifiP2pMonitor monitor) {
70            super(iface, monitor);
71        }
72    }
73
74    @Before
75    public void setUp() throws Exception {
76        MockitoAnnotations.initMocks(this);
77        mMonitor = mock(WifiP2pMonitor.class);
78        mDut = new SupplicantP2pIfaceCallbackSpy(mIface, mMonitor);
79    }
80
81    /**
82     * Sunny day scenario for onDeviceFound call.
83     */
84    @Test
85    public void testOnDeviceFound_success() throws Exception {
86        byte[] fakePrimaryDeviceTypeBytes = { 0x01, 0x02, 0x03 };
87        String fakePrimaryDeviceTypeString = "010203";
88        String fakeDeviceName = "test device name";
89        short fakeConfigMethods = 0x1234;
90        byte fakeCapabilities = 123;
91        int fakeGroupCapabilities = 456;
92
93        doAnswer(new AnswerWithArguments() {
94            public void answer(String iface, WifiP2pDevice device) {
95                // NOTE: mDeviceAddress1Bytes seems to be ignored by
96                // legacy implementation of WifiP2pDevice.
97                assertEquals(iface, mIface);
98                assertEquals(device.deviceName, fakeDeviceName);
99                assertEquals(device.primaryDeviceType, fakePrimaryDeviceTypeString);
100                assertEquals(device.deviceCapability, fakeCapabilities);
101                assertEquals(device.groupCapability, fakeGroupCapabilities);
102                assertEquals(device.wpsConfigMethodsSupported, fakeConfigMethods);
103                assertEquals(device.deviceAddress, mDeviceAddress2String);
104                assertEquals(device.status, WifiP2pDevice.AVAILABLE);
105            }
106        })
107        .when(mMonitor).broadcastP2pDeviceFound(
108                anyString(), any(WifiP2pDevice.class));
109
110        mDut.onDeviceFound(
111                mDeviceAddress1Bytes, mDeviceAddress2Bytes,
112                fakePrimaryDeviceTypeBytes,
113                fakeDeviceName, fakeConfigMethods,
114                fakeCapabilities, fakeGroupCapabilities,
115                mDeviceInfoBytes);
116
117        mDut.onDeviceFound(
118                mDeviceAddress1Bytes, mDeviceAddress2Bytes,
119                fakePrimaryDeviceTypeBytes,
120                fakeDeviceName, fakeConfigMethods,
121                fakeCapabilities, fakeGroupCapabilities,
122                null);
123
124        // Make sure we issued a broadcast each time.
125        verify(mMonitor, times(2)).broadcastP2pDeviceFound(
126                anyString(), any(WifiP2pDevice.class));
127    }
128
129    /**
130     * Failing scenarios for onDeviceFound call.
131     */
132    @Test
133    public void testOnDeviceFound_invalidArguments() throws Exception {
134        byte[] fakePrimaryDeviceTypeBytes = { 0x01, 0x02, 0x03 };
135        String fakePrimaryDeviceTypeString = "010203";
136        String fakeDeviceName = "test device name";
137        short fakeConfigMethods = 0x1234;
138        byte fakeCapabilities = 123;
139        int fakeGroupCapabilities = 456;
140
141        mDut.onDeviceFound(
142                mDeviceAddress2Bytes, null,
143                fakePrimaryDeviceTypeBytes,
144                fakeDeviceName, fakeConfigMethods,
145                fakeCapabilities, fakeGroupCapabilities,
146                mDeviceInfoBytes);
147        verify(mMonitor, never()).broadcastP2pDeviceFound(
148                anyString(), any(WifiP2pDevice.class));
149
150
151        mDut.onDeviceFound(
152                mDeviceAddress1Bytes, mDeviceAddress2Bytes,
153                null,
154                fakeDeviceName, fakeConfigMethods,
155                fakeCapabilities, fakeGroupCapabilities,
156                mDeviceInfoBytes);
157        verify(mMonitor, never()).broadcastP2pDeviceFound(
158                anyString(), any(WifiP2pDevice.class));
159
160
161        mDut.onDeviceFound(
162                mDeviceAddress1Bytes, mDeviceAddress2Bytes,
163                fakePrimaryDeviceTypeBytes,
164                null, fakeConfigMethods,
165                fakeCapabilities, fakeGroupCapabilities,
166                mDeviceInfoBytes);
167        verify(mMonitor, never()).broadcastP2pDeviceFound(
168                anyString(), any(WifiP2pDevice.class));
169
170
171        mDut.onDeviceFound(
172                mDeviceAddress1Bytes, mDeviceAddressInvalid1,
173                fakePrimaryDeviceTypeBytes,
174                null, fakeConfigMethods,
175                fakeCapabilities, fakeGroupCapabilities,
176                mDeviceInfoBytes);
177        verify(mMonitor, never()).broadcastP2pDeviceFound(
178                anyString(), any(WifiP2pDevice.class));
179
180
181        mDut.onDeviceFound(
182                mDeviceAddress1Bytes, mDeviceAddressInvalid2,
183                fakePrimaryDeviceTypeBytes,
184                null, fakeConfigMethods,
185                fakeCapabilities, fakeGroupCapabilities,
186                mDeviceInfoBytes);
187        verify(mMonitor, never()).broadcastP2pDeviceFound(
188                anyString(), any(WifiP2pDevice.class));
189    }
190
191    /**
192     * Sunny day scenario for onDeviceLost call.
193     */
194    @Test
195    public void testOnDeviceLost_success() throws Exception {
196        doAnswer(new AnswerWithArguments() {
197            public void answer(String iface, WifiP2pDevice device) {
198                assertEquals(iface, mIface);
199                assertEquals(device.deviceAddress, mDeviceAddress1String);
200                assertEquals(device.status, WifiP2pDevice.UNAVAILABLE);
201            }
202        })
203        .when(mMonitor).broadcastP2pDeviceLost(
204                anyString(), any(WifiP2pDevice.class));
205
206        mDut.onDeviceLost(mDeviceAddress1Bytes);
207
208        // Make sure we issued a broadcast each time.
209        verify(mMonitor, times(1)).broadcastP2pDeviceLost(
210                anyString(), any(WifiP2pDevice.class));
211    }
212
213    /**
214     * Failing scenarios for onDeviceLost call.
215     */
216    @Test
217    public void testOnDeviceLost_invalidArguments() throws Exception {
218        mDut.onDeviceLost(null);
219        verify(mMonitor, never()).broadcastP2pDeviceLost(
220                anyString(), any(WifiP2pDevice.class));
221
222        mDut.onDeviceLost(mDeviceAddressInvalid1);
223        verify(mMonitor, never()).broadcastP2pDeviceLost(
224                anyString(), any(WifiP2pDevice.class));
225
226        mDut.onDeviceLost(mDeviceAddressInvalid2);
227        verify(mMonitor, never()).broadcastP2pDeviceLost(
228                anyString(), any(WifiP2pDevice.class));
229    }
230
231    /**
232     * Sunny day scenario for onGoNegotiationRequest call.
233     */
234    @Test
235    public void testOnGoNegotiationRequest_success() throws Exception {
236        HashSet<Integer> setups = new HashSet<Integer>();
237
238        doAnswer(new AnswerWithArguments() {
239            public void answer(String iface, WifiP2pConfig config) {
240                assertEquals(iface, mIface);
241                assertNotNull(config.wps);
242                setups.add(config.wps.setup);
243                assertEquals(config.deviceAddress, mDeviceAddress1String);
244            }
245        })
246        .when(mMonitor).broadcastP2pGoNegotiationRequest(
247                anyString(), any(WifiP2pConfig.class));
248
249        mDut.onGoNegotiationRequest(mDeviceAddress1Bytes,
250                (short)ISupplicantP2pIfaceCallback.WpsDevPasswordId.USER_SPECIFIED);
251        assertTrue(setups.contains(WpsInfo.DISPLAY));
252
253        mDut.onGoNegotiationRequest(mDeviceAddress1Bytes,
254                (short)ISupplicantP2pIfaceCallback.WpsDevPasswordId.PUSHBUTTON);
255        assertTrue(setups.contains(WpsInfo.PBC));
256
257        mDut.onGoNegotiationRequest(mDeviceAddress1Bytes,
258                (short)ISupplicantP2pIfaceCallback.WpsDevPasswordId.REGISTRAR_SPECIFIED);
259        assertTrue(setups.contains(WpsInfo.KEYPAD));
260
261        // Invalid should default to PBC
262        setups.clear();
263        mDut.onGoNegotiationRequest(mDeviceAddress1Bytes, (short)0xffff);
264        assertTrue(setups.contains(WpsInfo.PBC));
265    }
266
267    /**
268     * Failing scenarios for onGoNegotiationRequest call.
269     */
270    @Test
271    public void testOnGoNegotiationRequest_invalidArguments() throws Exception {
272        mDut.onGoNegotiationRequest(null, (short)0);
273        verify(mMonitor, never()).broadcastP2pDeviceLost(
274                anyString(), any(WifiP2pDevice.class));
275
276        mDut.onGoNegotiationRequest(mDeviceAddressInvalid1, (short)0);
277        verify(mMonitor, never()).broadcastP2pDeviceLost(
278                anyString(), any(WifiP2pDevice.class));
279
280        mDut.onGoNegotiationRequest(mDeviceAddressInvalid2, (short)0);
281        verify(mMonitor, never()).broadcastP2pDeviceLost(
282                anyString(), any(WifiP2pDevice.class));
283    }
284
285    /**
286     * Sunny day scenario for onGroupStarted call.
287     */
288    @Test
289    public void testOnGroupStarted_success() throws Exception {
290        String fakeName = "group name";
291        String fakePassphrase = "secret";
292        ArrayList<Byte> fakeSsidBytesList = new ArrayList<Byte>() {{
293            add((byte)0x30);
294            add((byte)0x31);
295            add((byte)0x32);
296            add((byte)0x33);
297        }};
298        String fakeSsidString = "\"0123\"";
299        HashSet<String> passwords = new HashSet<String>();
300
301        doAnswer(new AnswerWithArguments() {
302            public void answer(String iface, WifiP2pGroup group) {
303                assertEquals(iface, mIface);
304                assertNotNull(group.getOwner());
305                assertEquals(group.getOwner().deviceAddress, mDeviceAddress1String);
306                assertEquals(group.getNetworkId(), WifiP2pGroup.PERSISTENT_NET_ID);
307                passwords.add(group.getPassphrase());
308                assertEquals(group.getInterface(), fakeName);
309                assertEquals(group.getNetworkName(), fakeSsidString);
310            }
311        })
312        .when(mMonitor).broadcastP2pGroupStarted(
313                anyString(), any(WifiP2pGroup.class));
314
315        mDut.onGroupStarted(
316                fakeName, true, fakeSsidBytesList, 1, null, fakePassphrase,
317                mDeviceAddress1Bytes, true);
318        assertTrue(passwords.contains(fakePassphrase));
319
320        mDut.onGroupStarted(
321                fakeName, true, fakeSsidBytesList, 1, null, null,
322                mDeviceAddress1Bytes, true);
323        assertTrue(passwords.contains(null));
324
325        verify(mMonitor, times(2)).broadcastP2pGroupStarted(
326                anyString(), any(WifiP2pGroup.class));
327    }
328
329    /**
330     * Failing scenarios for onGroupStarted call.
331     */
332    @Test
333    public void testOnGroupStarted_invalidArguments() throws Exception {
334        String fakeName = "group name";
335        String fakePassphrase = "secret";
336        ArrayList<Byte> fakeSsidBytesList = new ArrayList<Byte>() {{
337            add((byte)0x30);
338            add((byte)0x31);
339            add((byte)0x32);
340            add((byte)0x33);
341        }};
342        String fakeSsidString = "0123";
343
344        mDut.onGroupStarted(
345                null, true, fakeSsidBytesList, 1, null, fakePassphrase,
346                mDeviceAddress1Bytes, true);
347        verify(mMonitor, never()).broadcastP2pGroupStarted(
348                anyString(), any(WifiP2pGroup.class));
349
350        mDut.onGroupStarted(
351                fakeName, true, null, 1, null, fakePassphrase,
352                mDeviceAddress1Bytes, true);
353        verify(mMonitor, never()).broadcastP2pGroupStarted(
354                anyString(), any(WifiP2pGroup.class));
355
356        mDut.onGroupStarted(
357                fakeName, true, fakeSsidBytesList, 1, null, fakePassphrase,
358                null, true);
359        verify(mMonitor, never()).broadcastP2pGroupStarted(
360                anyString(), any(WifiP2pGroup.class));
361    }
362
363    /**
364     * Test provision disovery callback.
365     */
366    @Test
367    public void testOnProvisionDisconveryCompleted() throws Exception {
368        byte[] p2pDeviceAddr = DEVICE_ADDRESS;
369        boolean isRequest = false;
370        byte status = ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.SUCCESS;
371        short configMethods = WpsConfigMethods.DISPLAY;
372        String generatedPin = "12345678";
373
374        ArgumentCaptor<WifiP2pProvDiscEvent> discEventCaptor =
375                ArgumentCaptor.forClass(WifiP2pProvDiscEvent.class);
376        mDut.onProvisionDiscoveryCompleted(
377                p2pDeviceAddr, isRequest, status, configMethods, generatedPin);
378        verify(mMonitor).broadcastP2pProvisionDiscoveryShowPin(
379                anyString(), discEventCaptor.capture());
380        assertEquals(WifiP2pProvDiscEvent.SHOW_PIN, discEventCaptor.getValue().event);
381        assertEquals(generatedPin, discEventCaptor.getValue().pin);
382
383        configMethods = WpsConfigMethods.KEYPAD;
384        mDut.onProvisionDiscoveryCompleted(
385                p2pDeviceAddr, isRequest, status, configMethods, generatedPin);
386        verify(mMonitor).broadcastP2pProvisionDiscoveryEnterPin(
387                anyString(), discEventCaptor.capture());
388        assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, discEventCaptor.getValue().event);
389
390        configMethods = WpsConfigMethods.PUSHBUTTON;
391        mDut.onProvisionDiscoveryCompleted(
392                p2pDeviceAddr, isRequest, status, configMethods, generatedPin);
393        verify(mMonitor).broadcastP2pProvisionDiscoveryPbcResponse(
394                anyString(), discEventCaptor.capture());
395        assertEquals(WifiP2pProvDiscEvent.PBC_RSP, discEventCaptor.getValue().event);
396
397        isRequest = true;
398        mDut.onProvisionDiscoveryCompleted(
399                p2pDeviceAddr, isRequest, status, configMethods, generatedPin);
400        verify(mMonitor).broadcastP2pProvisionDiscoveryPbcRequest(
401                anyString(), discEventCaptor.capture());
402        assertEquals(WifiP2pProvDiscEvent.PBC_REQ, discEventCaptor.getValue().event);
403    }
404}
405