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