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.inOrder;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.verify;
25import static org.mockito.Mockito.when;
26
27import android.app.test.MockAnswerUtil.AnswerWithArguments;
28import android.hardware.wifi.supplicant.V1_0.ISupplicant;
29import android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
30import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
31import android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIface;
32import android.hardware.wifi.supplicant.V1_0.ISupplicantP2pNetwork;
33import android.hardware.wifi.supplicant.V1_0.IfaceType;
34import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
35import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
36import android.hidl.manager.V1_0.IServiceManager;
37import android.hidl.manager.V1_0.IServiceNotification;
38import android.net.wifi.WpsInfo;
39import android.net.wifi.p2p.WifiP2pConfig;
40import android.net.wifi.p2p.WifiP2pDevice;
41import android.net.wifi.p2p.WifiP2pGroup;
42import android.net.wifi.p2p.WifiP2pGroupList;
43import android.net.wifi.p2p.WifiP2pManager;
44import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
45import android.os.IHwBinder;
46import android.os.RemoteException;
47import android.text.TextUtils;
48
49import com.android.server.wifi.util.NativeUtil;
50
51import org.junit.Assert.*;
52import org.junit.Before;
53import org.junit.Test;
54import org.mockito.ArgumentCaptor;
55import org.mockito.InOrder;
56import org.mockito.Mock;
57import org.mockito.MockitoAnnotations;
58
59import java.util.ArrayList;
60import java.util.Arrays;
61import java.util.HashMap;
62import java.util.HashSet;
63import java.util.Map;
64
65/**
66 * Unit tests for SupplicantP2pIfaceHal
67 */
68public class SupplicantP2pIfaceHalTest {
69    private static final String TAG = "SupplicantP2pIfaceHalTest";
70    private SupplicantP2pIfaceHal mDut;
71    @Mock IServiceManager mServiceManagerMock;
72    @Mock ISupplicant mISupplicantMock;
73    @Mock ISupplicantIface mISupplicantIfaceMock;
74    @Mock ISupplicantP2pIface mISupplicantP2pIfaceMock;
75    @Mock ISupplicantP2pNetwork mISupplicantP2pNetworkMock;
76
77    SupplicantStatus mStatusSuccess;
78    SupplicantStatus mStatusFailure;
79    RemoteException mRemoteException;
80    ISupplicant.IfaceInfo mStaIface;
81    ISupplicant.IfaceInfo mP2pIface;
82    ArrayList<ISupplicant.IfaceInfo> mIfaceInfoList;
83
84    final String mIfaceName = "virtual_interface_name";
85    final String mSsid = "\"SSID\"";
86    final ArrayList<Byte> mSsidBytes = new ArrayList<Byte>() {{
87        add((byte)'S'); add((byte)'S'); add((byte)'I'); add((byte)'D');
88    }};
89    final String mPeerMacAddress = "00:11:22:33:44:55";
90    final byte mPeerMacAddressBytes[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
91    final String mGroupOwnerMacAddress = "01:12:23:34:45:56";
92    final byte mGroupOwnerMacAddressBytes[] = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56 };
93    final String mInvalidMacAddress1 = "00:11:22:33:44";
94    final String mInvalidMacAddress2 = ":::::";
95    final String mInvalidMacAddress3 = "invalid";
96    final byte mInvalidMacAddressBytes1[] = null;
97    final byte mInvalidMacAddressBytes2[] = {};
98    final byte mInvalidMacAddressBytes3[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
99    final byte mInvalidMacAddressBytes4[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
100    HashSet<String> mInvalidMacAddresses = new HashSet<String>(Arrays.asList(
101            mInvalidMacAddress1, mInvalidMacAddress2,
102            mInvalidMacAddress3));
103    HashSet<byte[]> mInvalidMacAddressesBytes = new HashSet<byte[]>(Arrays.asList(
104            mInvalidMacAddressBytes1, mInvalidMacAddressBytes2,
105            mInvalidMacAddressBytes3, mInvalidMacAddressBytes4));
106
107    final String mInvalidService1 = null;
108    final String mInvalidService2 = "service";
109    final String mValidServiceRequestString = "30313233";
110    final byte[] mValidServiceRequestBytes = { 0x30, 0x31, 0x32, 0x33 };
111    final String mInvalidServiceRequestString = "not a hex string";
112    final String mInvalidUpnpService1 = "upnp";
113    final String mInvalidUpnpService2 = "upnp 1";
114    final String mInvalidUpnpService3 = "upnp invalid_number name";
115    final String mInvalidBonjourService1 = "bonjour";
116    final String mInvalidBonjourService2 = "bonjour 123456";
117    final String mInvalidBonjourService3 = "bonjour invalid_hex 123456";
118    final String mInvalidBonjourService4 = "bonjour 123456 invalid_hex";
119    final String mValidUpnpService = "upnp 10 serviceName";
120    final int mValidUpnpServiceVersion = 16;
121    final String mValidUpnpServiceName = "serviceName";
122    final String mValidBonjourService = "bonjour 30313233 34353637";
123    final ArrayList<Byte> mValidBonjourServiceRequest = new ArrayList<Byte>() {{
124        add((byte)'0'); add((byte)'1'); add((byte)'2'); add((byte)'3');
125    }};
126    final ArrayList<Byte> mValidBonjourServiceResponse = new ArrayList<Byte>() {{
127        add((byte)'4'); add((byte)'5'); add((byte)'6'); add((byte)'7');
128    }};
129
130
131    private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
132            ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
133    private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
134            ArgumentCaptor.forClass(IServiceNotification.Stub.class);
135    private InOrder mInOrder;
136
137    private class SupplicantP2pIfaceHalSpy extends SupplicantP2pIfaceHal {
138        SupplicantP2pIfaceHalSpy() {
139            super(null);
140        }
141
142        @Override
143        protected IServiceManager getServiceManagerMockable() throws RemoteException {
144            return mServiceManagerMock;
145        }
146
147        @Override
148        protected ISupplicant getSupplicantMockable() throws RemoteException {
149            return mISupplicantMock;
150        }
151
152        @Override
153        protected ISupplicantP2pIface getP2pIfaceMockable(ISupplicantIface iface) {
154            return mISupplicantP2pIfaceMock;
155        }
156
157        @Override
158        protected ISupplicantP2pNetwork getP2pNetworkMockable(ISupplicantNetwork network) {
159            return mISupplicantP2pNetworkMock;
160        }
161    }
162
163    @Before
164    public void setUp() throws Exception {
165        MockitoAnnotations.initMocks(this);
166        mStatusSuccess = createSupplicantStatus(SupplicantStatusCode.SUCCESS);
167        mStatusFailure = createSupplicantStatus(SupplicantStatusCode.FAILURE_UNKNOWN);
168        mRemoteException = new RemoteException("Test Remote Exception");
169        mStaIface = createIfaceInfo(IfaceType.STA, "wlan0");
170        mP2pIface = createIfaceInfo(IfaceType.P2P, "p2p0");
171
172        mIfaceInfoList = new ArrayList<ISupplicant.IfaceInfo>();
173        mIfaceInfoList.add(mStaIface);
174        mIfaceInfoList.add(mP2pIface);
175
176        when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
177                anyLong())).thenReturn(true);
178        when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
179                any(IServiceNotification.Stub.class))).thenReturn(true);
180        when(mISupplicantMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
181                anyLong())).thenReturn(true);
182        when(mISupplicantP2pIfaceMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
183                anyLong())).thenReturn(true);
184        mDut = new SupplicantP2pIfaceHalSpy();
185    }
186
187    /**
188     * Sunny day scenario for SupplicantP2pIfaceHal initialization
189     * Asserts successful initialization
190     */
191    @Test
192    public void testInitialize_success() throws Exception {
193        executeAndValidateInitializationSequence(false, false, false);
194    }
195
196    /**
197     * Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called
198     * Ensures initialization fails.
199     */
200    @Test
201    public void testInitialize_remoteExceptionFailure() throws Exception {
202        executeAndValidateInitializationSequence(true, false, false);
203    }
204
205    /**
206     * Tests the initialization flow, with listInterfaces returning 0 interfaces.
207     * Ensures failure
208     */
209    @Test
210    public void testInitialize_zeroInterfacesFailure() throws Exception {
211        executeAndValidateInitializationSequence(false, true, false);
212    }
213
214    /**
215     * Tests the initialization flow, with a null interface being returned by getInterface.
216     * Ensures initialization fails.
217     */
218    @Test
219    public void testInitialize_nullInterfaceFailure() throws Exception {
220        executeAndValidateInitializationSequence(false, false, true);
221    }
222
223    /**
224     * Sunny day scenario for getName()
225     */
226    @Test
227    public void testGetName_success() throws Exception {
228
229        doAnswer(new AnswerWithArguments() {
230            public void answer(ISupplicantIface.getNameCallback cb) throws RemoteException {
231                cb.onValues(mStatusSuccess, mIfaceName);
232            }
233        })
234        .when(mISupplicantP2pIfaceMock).getName(any(ISupplicantIface.getNameCallback.class));
235
236        // Default value when service is not initialized.
237        assertNull(mDut.getName());
238        executeAndValidateInitializationSequence(false, false, false);
239        assertEquals(mIfaceName, mDut.getName());
240    }
241
242    /**
243     * Verify that getName returns null, if status is not SUCCESS.
244     */
245    @Test
246    public void testGetName_failure() throws Exception {
247        executeAndValidateInitializationSequence(false, false, false);
248        doAnswer(new AnswerWithArguments() {
249            public void answer(ISupplicantIface.getNameCallback cb) throws RemoteException {
250                cb.onValues(mStatusFailure, "none");
251            }
252        })
253        .when(mISupplicantP2pIfaceMock).getName(any(ISupplicantIface.getNameCallback.class));
254        assertNull(mDut.getName());
255        // Check that service is still alive.
256        assertTrue(mDut.isInitializationComplete());
257    }
258
259    /**
260     * Verify that getName disconnects and returns null, if HAL throws exception.
261     */
262    @Test
263    public void testGetName_exception() throws Exception {
264        executeAndValidateInitializationSequence(false, false, false);
265        doAnswer(new AnswerWithArguments() {
266            public void answer(ISupplicantIface.getNameCallback cb) throws RemoteException {
267                throw new RemoteException("Test");
268            }
269        })
270        .when(mISupplicantP2pIfaceMock).getName(any(ISupplicantIface.getNameCallback.class));
271        assertNull(mDut.getName());
272        // Check service is dead.
273        assertFalse(mDut.isInitializationComplete());
274    }
275
276
277    /**
278     * Sunny day scenario for find()
279     */
280    @Test
281    public void testFind_success() throws Exception {
282        when(mISupplicantP2pIfaceMock.find(anyInt())).thenReturn(mStatusSuccess);
283        // Default value when service is not yet initialized.
284        assertFalse(mDut.find(1));
285
286        executeAndValidateInitializationSequence(false, false, false);
287        assertTrue(mDut.find(1));
288        assertFalse(mDut.find(-1));
289    }
290
291    /**
292     * Verify that find returns false, if status is not SUCCESS.
293     */
294    @Test
295    public void testFind_failure() throws Exception {
296        executeAndValidateInitializationSequence(false, false, false);
297        when(mISupplicantP2pIfaceMock.find(anyInt())).thenReturn(mStatusFailure);
298        assertFalse(mDut.find(1));
299        // Check that service is still alive.
300        assertTrue(mDut.isInitializationComplete());
301    }
302
303    /**
304     * Verify that find disconnects and returns false, if HAL throws exception.
305     */
306    @Test
307    public void testFind_exception() throws Exception {
308        executeAndValidateInitializationSequence(false, false, false);
309        when(mISupplicantP2pIfaceMock.find(anyInt())).thenThrow(mRemoteException);
310        assertFalse(mDut.find(0));
311        // Check service is dead.
312        assertFalse(mDut.isInitializationComplete());
313    }
314
315
316    /**
317     * Sunny day scenario for stopFind()
318     */
319    @Test
320    public void testStopFind_success() throws Exception {
321        when(mISupplicantP2pIfaceMock.stopFind()).thenReturn(mStatusSuccess);
322        // Default value when service is not yet initialized.
323        assertFalse(mDut.stopFind());
324        executeAndValidateInitializationSequence(false, false, false);
325        assertTrue(mDut.stopFind());
326    }
327
328    /**
329     * Verify that stopFind returns false, if status is not SUCCESS.
330     */
331    @Test
332    public void testStopFind_failure() throws Exception {
333        executeAndValidateInitializationSequence(false, false, false);
334        when(mISupplicantP2pIfaceMock.stopFind()).thenReturn(mStatusFailure);
335        assertFalse(mDut.stopFind());
336        // Check that service is still alive.
337        assertTrue(mDut.isInitializationComplete());
338    }
339
340    /**
341     * Verify that stopFind disconnects and returns false, if HAL throws exception.
342     */
343    @Test
344    public void testStopFind_exception() throws Exception {
345        executeAndValidateInitializationSequence(false, false, false);
346        when(mISupplicantP2pIfaceMock.stopFind()).thenThrow(mRemoteException);
347        assertFalse(mDut.stopFind());
348        // Check service is dead.
349        assertFalse(mDut.isInitializationComplete());
350    }
351
352
353    /**
354     * Sunny day scenario for flush()
355     */
356    @Test
357    public void testFlush_success() throws Exception {
358        when(mISupplicantP2pIfaceMock.flush()).thenReturn(mStatusSuccess);
359        // Default value when service is not yet initialized.
360        assertFalse(mDut.flush());
361        executeAndValidateInitializationSequence(false, false, false);
362        assertTrue(mDut.flush());
363    }
364
365    /**
366     * Verify that flush returns false, if status is not SUCCESS.
367     */
368    @Test
369    public void testFlush_failure() throws Exception {
370        executeAndValidateInitializationSequence(false, false, false);
371        when(mISupplicantP2pIfaceMock.flush()).thenReturn(mStatusFailure);
372        assertFalse(mDut.flush());
373        // Check that service is still alive.
374        assertTrue(mDut.isInitializationComplete());
375    }
376
377    /**
378     * Verify that flush disconnects and returns false, if HAL throws exception.
379     */
380    @Test
381    public void testFlush_exception() throws Exception {
382        executeAndValidateInitializationSequence(false, false, false);
383        when(mISupplicantP2pIfaceMock.flush()).thenThrow(mRemoteException);
384        assertFalse(mDut.flush());
385        // Check service is dead.
386        assertFalse(mDut.isInitializationComplete());
387    }
388
389
390    /**
391     * Sunny day scenario for serviceFlush()
392     */
393    @Test
394    public void testServiceFlush_success() throws Exception {
395        when(mISupplicantP2pIfaceMock.flushServices()).thenReturn(mStatusSuccess);
396        // Default value when service is not initialized.
397        assertFalse(mDut.serviceFlush());
398        executeAndValidateInitializationSequence(false, false, false);
399        assertTrue(mDut.serviceFlush());
400    }
401
402    /**
403     * Verify that serviceFlush returns false, if status is not SUCCESS.
404     */
405    @Test
406    public void testServiceFlush_failure() throws Exception {
407        executeAndValidateInitializationSequence(false, false, false);
408        when(mISupplicantP2pIfaceMock.flushServices()).thenReturn(mStatusFailure);
409        assertFalse(mDut.serviceFlush());
410        // Check that service is still alive.
411        assertTrue(mDut.isInitializationComplete());
412    }
413
414    /**
415     * Verify that serviceFlush disconnects and returns false, if HAL throws exception.
416     */
417    @Test
418    public void testServiceFlush_exception() throws Exception {
419        executeAndValidateInitializationSequence(false, false, false);
420        when(mISupplicantP2pIfaceMock.flushServices()).thenThrow(mRemoteException);
421        assertFalse(mDut.serviceFlush());
422        // Check service is dead.
423        assertFalse(mDut.isInitializationComplete());
424    }
425
426
427    /**
428     * Sunny day scenario for setPowerSave()
429     */
430    @Test
431    public void testSetPowerSave_success() throws Exception {
432        when(mISupplicantP2pIfaceMock.setPowerSave(eq(mIfaceName), anyBoolean()))
433                .thenReturn(mStatusSuccess);
434        // Default value when service is not initialized.
435        assertFalse(mDut.setPowerSave(mIfaceName, true));
436        executeAndValidateInitializationSequence(false, false, false);
437        assertTrue(mDut.setPowerSave(mIfaceName, true));
438    }
439
440    /**
441     * Verify that setPowerSave returns false, if status is not SUCCESS.
442     */
443    @Test
444    public void testSetPowerSave_failure() throws Exception {
445        executeAndValidateInitializationSequence(false, false, false);
446        when(mISupplicantP2pIfaceMock.setPowerSave(eq(mIfaceName), anyBoolean()))
447                .thenReturn(mStatusFailure);
448        assertFalse(mDut.setPowerSave(mIfaceName, true));
449        // Check that service is still alive.
450        assertTrue(mDut.isInitializationComplete());
451    }
452
453    /**
454     * Verify that setPowerSave disconnects and returns false, if HAL throws exception.
455     */
456    @Test
457    public void testSetPowerSave_exception() throws Exception {
458        executeAndValidateInitializationSequence(false, false, false);
459        when(mISupplicantP2pIfaceMock.setPowerSave(eq(mIfaceName), anyBoolean()))
460                .thenThrow(mRemoteException);
461        assertFalse(mDut.setPowerSave(mIfaceName, true));
462        // Check service is dead.
463        assertFalse(mDut.isInitializationComplete());
464    }
465
466
467    /**
468     * Sunny day scenario for setGroupIdle()
469     */
470    @Test
471    public void testSetGroupIdle_success() throws Exception {
472        when(mISupplicantP2pIfaceMock.setGroupIdle(eq(mIfaceName), anyInt()))
473                .thenReturn(mStatusSuccess);
474        // Default value when service is not initialized.
475        assertFalse(mDut.setGroupIdle(mIfaceName, 1));
476        executeAndValidateInitializationSequence(false, false, false);
477        assertTrue(mDut.setGroupIdle(mIfaceName, 1));
478        assertFalse(mDut.setGroupIdle(mIfaceName, -1));
479    }
480
481    /**
482     * Verify that setGroupIdle returns false, if status is not SUCCESS.
483     */
484    @Test
485    public void testSetGroupIdle_failure() throws Exception {
486        executeAndValidateInitializationSequence(false, false, false);
487        when(mISupplicantP2pIfaceMock.setGroupIdle(eq(mIfaceName), anyInt()))
488                .thenReturn(mStatusFailure);
489        assertFalse(mDut.setGroupIdle(mIfaceName, 1));
490        // Check that service is still alive.
491        assertTrue(mDut.isInitializationComplete());
492    }
493
494    /**
495     * Verify that setGroupIdle disconnects and returns false, if HAL throws exception.
496     */
497    @Test
498    public void testSetGroupIdle_exception() throws Exception {
499        executeAndValidateInitializationSequence(false, false, false);
500        when(mISupplicantP2pIfaceMock.setGroupIdle(eq(mIfaceName), anyInt()))
501                .thenThrow(mRemoteException);
502        assertFalse(mDut.setGroupIdle(mIfaceName, 1));
503        // Check service is dead.
504        assertFalse(mDut.isInitializationComplete());
505    }
506
507
508    /**
509     * Sunny day scenario for setSsidPostfix()
510     */
511    @Test
512    public void testSetSsidPostfix_success() throws Exception {
513        String ssid = "SSID POSTFIX";
514        when(mISupplicantP2pIfaceMock.setSsidPostfix(eq(NativeUtil.decodeSsid("\"" + ssid + "\""))))
515                .thenReturn(mStatusSuccess);
516        // Default value when service is not initialized.
517        assertFalse(mDut.setSsidPostfix(ssid));
518        executeAndValidateInitializationSequence(false, false, false);
519        assertTrue(mDut.setSsidPostfix(ssid));
520        assertFalse(mDut.setSsidPostfix(null));
521    }
522
523    /**
524     * Verify that setSsidPostfix returns false, if status is not SUCCESS.
525     */
526    @Test
527    public void testSetSsidPostfix_failure() throws Exception {
528        String ssid = "SSID POSTFIX";
529        executeAndValidateInitializationSequence(false, false, false);
530        when(mISupplicantP2pIfaceMock.setSsidPostfix(eq(NativeUtil.decodeSsid("\"" + ssid + "\""))))
531                .thenReturn(mStatusFailure);
532        assertFalse(mDut.setSsidPostfix(ssid));
533        // Check that service is still alive.
534        assertTrue(mDut.isInitializationComplete());
535    }
536
537    /**
538     * Verify that setSsidPostfix disconnects and returns false, if HAL throws exception.
539     */
540    @Test
541    public void testSetSsidPostfix_exception() throws Exception {
542        String ssid = "SSID POSTFIX";
543        executeAndValidateInitializationSequence(false, false, false);
544        when(mISupplicantP2pIfaceMock.setSsidPostfix(eq(NativeUtil.decodeSsid("\"" + ssid + "\""))))
545                .thenThrow(mRemoteException);
546        assertFalse(mDut.setSsidPostfix(ssid));
547        // Check service is dead.
548        assertFalse(mDut.isInitializationComplete());
549    }
550
551
552    /**
553     * Sunny day scenario for connect()
554     */
555    @Test
556    public void testConnect_success() throws Exception {
557        final String configPin = "12345";
558        final HashSet<Integer> methods = new HashSet<>();
559
560        doAnswer(new AnswerWithArguments() {
561            public void answer(byte[] peer, int method, String pin, boolean joinExisting,
562                    boolean persistent, int goIntent,
563                    ISupplicantP2pIface.connectCallback cb) throws RemoteException {
564                methods.add(method);
565
566                if (method == ISupplicantP2pIface.WpsProvisionMethod.DISPLAY
567                        && TextUtils.isEmpty(pin)) {
568                    // Return the configPin for DISPLAY method if the pin was not provided.
569                    cb.onValues(mStatusSuccess, configPin);
570                } else {
571                    if (method != ISupplicantP2pIface.WpsProvisionMethod.PBC) {
572                        // PIN is only required for PIN methods.
573                        assertEquals(pin, configPin);
574                    }
575                    // For all the other cases, there is no generated pin.
576                    cb.onValues(mStatusSuccess, "");
577                }
578            }
579        })
580        .when(mISupplicantP2pIfaceMock).connect(
581                eq(mPeerMacAddressBytes), anyInt(), anyString(), anyBoolean(), anyBoolean(),
582                anyInt(), any(ISupplicantP2pIface.connectCallback.class));
583
584        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, "");
585
586        // Default value when service is not initialized.
587        assertNull(mDut.connect(config, false));
588
589        executeAndValidateInitializationSequence(false, false, false);
590
591        assertEquals(configPin, mDut.connect(config, false));
592        assertTrue(methods.contains(ISupplicantP2pIface.WpsProvisionMethod.DISPLAY));
593        methods.clear();
594
595        config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, configPin);
596        assertTrue(mDut.connect(config, false).isEmpty());
597        assertTrue(methods.contains(ISupplicantP2pIface.WpsProvisionMethod.DISPLAY));
598        methods.clear();
599
600        config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
601        assertTrue(mDut.connect(config, false).isEmpty());
602        assertTrue(methods.contains(ISupplicantP2pIface.WpsProvisionMethod.PBC));
603        methods.clear();
604
605        config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.KEYPAD, configPin);
606        assertTrue(mDut.connect(config, false).isEmpty());
607        assertTrue(methods.contains(ISupplicantP2pIface.WpsProvisionMethod.KEYPAD));
608    }
609
610    /**
611     * Test connect with invalid arguments.
612     */
613    @Test
614    public void testConnect_invalidArguments() throws Exception {
615        executeAndValidateInitializationSequence(false, false, false);
616        doAnswer(new AnswerWithArguments() {
617            public void answer(byte[] peer, int method, String pin, boolean joinExisting,
618                    boolean persistent, int goIntent,
619                    ISupplicantP2pIface.connectCallback cb) throws RemoteException {
620                cb.onValues(mStatusSuccess, pin);
621            }
622        })
623        .when(mISupplicantP2pIfaceMock).connect(
624                any(byte[].class), anyInt(), anyString(), anyBoolean(), anyBoolean(),
625                anyInt(), any(ISupplicantP2pIface.connectCallback.class));
626
627        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, "");
628
629        // unsupported.
630        config.wps.setup = -1;
631        assertNull(mDut.connect(config, false));
632
633        // Invalid peer address.
634        config.wps.setup = WpsInfo.DISPLAY;
635        for (String address : mInvalidMacAddresses) {
636            config.deviceAddress = address;
637            assertNull(mDut.connect(config, false));
638        }
639
640        // null pin not valid.
641        config.wps.setup = WpsInfo.DISPLAY;
642        config.wps.pin = null;
643        assertNull(mDut.connect(config, false));
644
645        // Pin should be empty for PBC.
646        config.wps.setup = WpsInfo.PBC;
647        config.wps.pin = "03455323";
648        assertNull(mDut.connect(config, false));
649    }
650
651    /**
652     * Verify that connect returns null, if status is not SUCCESS.
653     */
654    @Test
655    public void testConnect_failure() throws Exception {
656        final String configPin = "12345";
657        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, configPin);
658
659        executeAndValidateInitializationSequence(false, false, false);
660        doAnswer(new AnswerWithArguments() {
661            public void answer(byte[] peer, int method, String pin, boolean joinExisting,
662                    boolean persistent, int goIntent,
663                    ISupplicantP2pIface.connectCallback cb) throws RemoteException {
664                cb.onValues(mStatusFailure, null);
665            }
666        })
667        .when(mISupplicantP2pIfaceMock).connect(
668                eq(mPeerMacAddressBytes), anyInt(), anyString(), anyBoolean(), anyBoolean(),
669                anyInt(), any(ISupplicantP2pIface.connectCallback.class));
670
671        assertNull(mDut.connect(config, false));
672        // Check that service is still alive.
673        assertTrue(mDut.isInitializationComplete());
674    }
675
676    /**
677     * Verify that connect disconnects and returns null, if HAL throws exception.
678     */
679    @Test
680    public void testConnect_exception() throws Exception {
681        final String configPin = "12345";
682        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, configPin);
683
684        doThrow(mRemoteException)
685        .when(mISupplicantP2pIfaceMock).connect(
686                eq(mPeerMacAddressBytes), anyInt(), anyString(), anyBoolean(), anyBoolean(),
687                anyInt(), any(ISupplicantP2pIface.connectCallback.class));
688
689        assertNull(mDut.connect(config, false));
690        // Check service is dead.
691        assertFalse(mDut.isInitializationComplete());
692    }
693
694
695    /**
696     * Sunny day scenario for cancelConnect()
697     */
698    @Test
699    public void testCancelConnect_success() throws Exception {
700        when(mISupplicantP2pIfaceMock.cancelConnect())
701                .thenReturn(mStatusSuccess);
702        // Default value when service is not initialized.
703        assertFalse(mDut.cancelConnect());
704        executeAndValidateInitializationSequence(false, false, false);
705        assertTrue(mDut.cancelConnect());
706    }
707
708    /**
709     * Verify that cancelConnect returns false, if status is not SUCCESS.
710     */
711    @Test
712    public void testCancelConnect_failure() throws Exception {
713        executeAndValidateInitializationSequence(false, false, false);
714        when(mISupplicantP2pIfaceMock.cancelConnect())
715                .thenReturn(mStatusFailure);
716        assertFalse(mDut.cancelConnect());
717        // Check that service is still alive.
718        assertTrue(mDut.isInitializationComplete());
719    }
720
721    /**
722     * Verify that cancelConnect disconnects and returns false, if HAL throws exception.
723     */
724    @Test
725    public void testCancelConnect_exception() throws Exception {
726        String ssid = "\"SSID POSTFIX\"";
727        executeAndValidateInitializationSequence(false, false, false);
728        when(mISupplicantP2pIfaceMock.cancelConnect())
729                .thenThrow(mRemoteException);
730        assertFalse(mDut.cancelConnect());
731        // Check service is dead.
732        assertFalse(mDut.isInitializationComplete());
733    }
734
735
736    /**
737     * Sunny day scenario for provisionDiscovery()
738     */
739    @Test
740    public void testProvisionDiscovery_success() throws Exception {
741        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
742
743        when(mISupplicantP2pIfaceMock.provisionDiscovery(
744                eq(mPeerMacAddressBytes), anyInt()))
745                .thenReturn(mStatusSuccess);
746        // Default value when service is not initialized.
747        assertFalse(mDut.provisionDiscovery(config));
748        executeAndValidateInitializationSequence(false, false, false);
749        assertTrue(mDut.provisionDiscovery(config));
750    }
751
752    /**
753     * Test provisionDiscovery with invalid arguments.
754     */
755    @Test
756    public void testProvisionDiscovery_invalidArguments() throws Exception {
757        when(mISupplicantP2pIfaceMock.provisionDiscovery(
758                eq(mPeerMacAddressBytes), anyInt()))
759                .thenReturn(mStatusSuccess);
760        executeAndValidateInitializationSequence(false, false, false);
761
762        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
763
764        // Unsupported method.
765        config.wps.setup = -1;
766        assertFalse(mDut.provisionDiscovery(config));
767
768        config.wps.setup = WpsInfo.PBC;
769        for (String address : mInvalidMacAddresses) {
770            config.deviceAddress = address;
771            assertFalse(mDut.provisionDiscovery(config));
772        }
773    }
774
775    /**
776     * Verify that provisionDiscovery returns false, if status is not SUCCESS.
777     */
778    @Test
779    public void testProvisionDiscovery_failure() throws Exception {
780        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
781
782        executeAndValidateInitializationSequence(false, false, false);
783        when(mISupplicantP2pIfaceMock.provisionDiscovery(
784                eq(mPeerMacAddressBytes), anyInt()))
785                .thenReturn(mStatusFailure);
786        assertFalse(mDut.provisionDiscovery(config));
787        // Check that service is still alive.
788        assertTrue(mDut.isInitializationComplete());
789    }
790
791    /**
792     * Verify that provisionDiscovery disconnects and returns false, if HAL throws exception.
793     */
794    @Test
795    public void testProvisionDiscovery_exception() throws Exception {
796        WifiP2pConfig config = createDummyP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
797
798        executeAndValidateInitializationSequence(false, false, false);
799        when(mISupplicantP2pIfaceMock.provisionDiscovery(
800                eq(mPeerMacAddressBytes), anyInt()))
801                .thenThrow(mRemoteException);
802        assertFalse(mDut.provisionDiscovery(config));
803        // Check service is dead.
804        assertFalse(mDut.isInitializationComplete());
805    }
806
807
808    /**
809     * Sunny day scenario for invite()
810     */
811    @Test
812    public void testInvite_success() throws Exception {
813        WifiP2pGroup group = createDummyP2pGroup();
814
815        when(mISupplicantP2pIfaceMock.invite(
816                eq(mIfaceName), eq(mGroupOwnerMacAddressBytes), eq(mPeerMacAddressBytes)))
817                .thenReturn(mStatusSuccess);
818        // Default value when service is not initialized.
819        assertFalse(mDut.invite(group, mPeerMacAddress));
820        executeAndValidateInitializationSequence(false, false, false);
821        assertTrue(mDut.invite(group, mPeerMacAddress));
822    }
823
824    /**
825     * Invite with invalid arguments.
826     */
827    @Test
828    public void testInvite_invalidArguments() throws Exception {
829        WifiP2pGroup group = createDummyP2pGroup();
830
831        executeAndValidateInitializationSequence(false, false, false);
832        when(mISupplicantP2pIfaceMock.invite(
833                anyString(), any(byte[].class), any(byte[].class)))
834                .thenReturn(mStatusSuccess);
835
836        for (String address : mInvalidMacAddresses) {
837            assertFalse(mDut.invite(group, address));
838        }
839
840        for (String address : mInvalidMacAddresses) {
841            group.getOwner().deviceAddress = address;
842            assertFalse(mDut.invite(group, mPeerMacAddress));
843        }
844
845        group.setOwner(null);
846        assertFalse(mDut.invite(group, mPeerMacAddress));
847        assertFalse(mDut.invite(null, mPeerMacAddress));
848    }
849
850    /**
851     * Verify that invite returns false, if status is not SUCCESS.
852     */
853    @Test
854    public void testInvite_failure() throws Exception {
855        WifiP2pGroup group = createDummyP2pGroup();
856
857        executeAndValidateInitializationSequence(false, false, false);
858        when(mISupplicantP2pIfaceMock.invite(
859                anyString(), any(byte[].class), any(byte[].class)))
860                .thenReturn(mStatusFailure);
861        assertFalse(mDut.invite(group, mPeerMacAddress));
862        // Check that service is still alive.
863        assertTrue(mDut.isInitializationComplete());
864    }
865
866    /**
867     * Verify that invite disconnects and returns false, if HAL throws exception.
868     */
869    @Test
870    public void testInvite_exception() throws Exception {
871        WifiP2pGroup group = createDummyP2pGroup();
872
873        executeAndValidateInitializationSequence(false, false, false);
874        when(mISupplicantP2pIfaceMock.invite(
875                anyString(), any(byte[].class), any(byte[].class)))
876                .thenThrow(mRemoteException);
877        assertFalse(mDut.invite(group, mPeerMacAddress));
878        // Check service is dead.
879        assertFalse(mDut.isInitializationComplete());
880    }
881
882
883    /**
884     * Sunny day scenario for reject()
885     */
886    @Test
887    public void testReject_success() throws Exception {
888        when(mISupplicantP2pIfaceMock.reject(eq(mPeerMacAddressBytes)))
889                .thenReturn(mStatusSuccess);
890        // Default value when service is not initialized.
891        assertFalse(mDut.reject(mPeerMacAddress));
892        executeAndValidateInitializationSequence(false, false, false);
893        assertTrue(mDut.reject(mPeerMacAddress));
894    }
895
896    /**
897     * Reject with invalid arguments.
898     */
899    @Test
900    public void testReject_invalidArguments() throws Exception {
901        executeAndValidateInitializationSequence(false, false, false);
902        when(mISupplicantP2pIfaceMock.reject(any(byte[].class)))
903                .thenReturn(mStatusSuccess);
904
905        for (String address : mInvalidMacAddresses) {
906            assertFalse(mDut.reject(address));
907        }
908    }
909
910    /**
911     * Verify that reject returns false, if status is not SUCCESS.
912     */
913    @Test
914    public void testReject_failure() throws Exception {
915        executeAndValidateInitializationSequence(false, false, false);
916        when(mISupplicantP2pIfaceMock.reject(any(byte[].class)))
917                .thenReturn(mStatusFailure);
918        assertFalse(mDut.reject(mPeerMacAddress));
919        // Check that service is still alive.
920        assertTrue(mDut.isInitializationComplete());
921    }
922
923    /**
924     * Verify that reject disconnects and returns false, if HAL throws exception.
925     */
926    @Test
927    public void testReject_exception() throws Exception {
928        executeAndValidateInitializationSequence(false, false, false);
929        when(mISupplicantP2pIfaceMock.reject(any(byte[].class)))
930                .thenThrow(mRemoteException);
931        assertFalse(mDut.reject(mPeerMacAddress));
932        // Check service is dead.
933        assertFalse(mDut.isInitializationComplete());
934    }
935
936
937    /**
938     * Sunny day scenario for getDeviceAddress()
939     */
940    @Test
941    public void testGetDeviceAddress_success() throws Exception {
942        doAnswer(new AnswerWithArguments() {
943            public void answer(ISupplicantP2pIface.getDeviceAddressCallback cb) {
944                cb.onValues(mStatusSuccess, mPeerMacAddressBytes);
945            }
946        })
947        .when(mISupplicantP2pIfaceMock).getDeviceAddress(
948                any(ISupplicantP2pIface.getDeviceAddressCallback.class));
949
950        // Default value when service is not initialized.
951        assertNull(mDut.getDeviceAddress());
952        executeAndValidateInitializationSequence(false, false, false);
953        assertEquals(mPeerMacAddress, mDut.getDeviceAddress());
954    }
955
956    /**
957     * Test getDeviceAddress() when invalid mac address is being reported.
958     */
959    @Test
960    public void testGetDeviceAddress_invalidResult() throws Exception {
961        executeAndValidateInitializationSequence(false, false, false);
962        HashSet<byte[]> addresses = new HashSet<byte[]>(Arrays.asList(
963                mInvalidMacAddressBytes1, mInvalidMacAddressBytes2,
964                mInvalidMacAddressBytes3, mInvalidMacAddressBytes4));
965
966        doAnswer(new AnswerWithArguments() {
967            public void answer(ISupplicantP2pIface.getDeviceAddressCallback cb) {
968                byte[] address = addresses.iterator().next();
969                cb.onValues(mStatusSuccess, address);
970                addresses.remove(address);
971            }
972        })
973        .when(mISupplicantP2pIfaceMock).getDeviceAddress(
974                any(ISupplicantP2pIface.getDeviceAddressCallback.class));
975
976        // Default value when service is not initialized.
977        while (!addresses.isEmpty()) {
978            assertNull(mDut.getDeviceAddress());
979        }
980    }
981
982    /**
983     * Verify that getDeviceAddress returns false, if status is not SUCCESS.
984     */
985    @Test
986    public void testGetDeviceAddress_failure() throws Exception {
987        executeAndValidateInitializationSequence(false, false, false);
988        doAnswer(new AnswerWithArguments() {
989            public void answer(ISupplicantP2pIface.getDeviceAddressCallback cb) {
990                cb.onValues(mStatusFailure, null);
991            }
992        })
993        .when(mISupplicantP2pIfaceMock).getDeviceAddress(
994                any(ISupplicantP2pIface.getDeviceAddressCallback.class));
995
996        assertNull(mDut.getDeviceAddress());
997        // Check that service is still alive.
998        assertTrue(mDut.isInitializationComplete());
999    }
1000
1001    /**
1002     * Verify that getDeviceAddress disconnects and returns false, if HAL throws exception.
1003     */
1004    @Test
1005    public void testGetDeviceAddress_exception() throws Exception {
1006        executeAndValidateInitializationSequence(false, false, false);
1007        doThrow(mRemoteException).when(mISupplicantP2pIfaceMock).getDeviceAddress(
1008                any(ISupplicantP2pIface.getDeviceAddressCallback.class));
1009
1010        assertNull(mDut.getDeviceAddress());
1011        // Check service is dead.
1012        assertFalse(mDut.isInitializationComplete());
1013    }
1014
1015
1016    /**
1017     * Sunny day scenario for getSsid()
1018     */
1019    @Test
1020    public void testGetSsid_success() throws Exception {
1021        doAnswer(new AnswerWithArguments() {
1022            public void answer(byte[] address, ISupplicantP2pIface.getSsidCallback cb) {
1023                cb.onValues(mStatusSuccess, mSsidBytes);
1024            }
1025        })
1026        .when(mISupplicantP2pIfaceMock).getSsid(
1027                eq(mPeerMacAddressBytes),
1028                any(ISupplicantP2pIface.getSsidCallback.class));
1029
1030        // Default value when service is not initialized.
1031        assertNull(mDut.getSsid(mPeerMacAddress));
1032        executeAndValidateInitializationSequence(false, false, false);
1033        assertEquals(mSsid, mDut.getSsid(mPeerMacAddress));
1034    }
1035
1036    /**
1037     * Test getSsid() with invalid argument and response.
1038     */
1039    @Test
1040    public void testGetSsid_invalidArguments() throws Exception {
1041        executeAndValidateInitializationSequence(false, false, false);
1042
1043        doAnswer(new AnswerWithArguments() {
1044            public void answer(byte[] address, ISupplicantP2pIface.getSsidCallback cb) {
1045                cb.onValues(mStatusSuccess, mSsidBytes);
1046            }
1047        })
1048        .when(mISupplicantP2pIfaceMock).getSsid(
1049                any(byte[].class), any(ISupplicantP2pIface.getSsidCallback.class));
1050
1051        for (String address : mInvalidMacAddresses) {
1052            assertNull(mDut.getSsid(address));
1053        }
1054
1055        // Simulate null response from HAL.
1056        doAnswer(new AnswerWithArguments() {
1057            public void answer(byte[] address, ISupplicantP2pIface.getSsidCallback cb) {
1058                cb.onValues(mStatusSuccess, null);
1059            }
1060        })
1061        .when(mISupplicantP2pIfaceMock).getSsid(
1062                any(byte[].class), any(ISupplicantP2pIface.getSsidCallback.class));
1063
1064        assertNull(mDut.getSsid(mPeerMacAddress));
1065    }
1066
1067    /**
1068     * Verify that getSsid returns false, if status is not SUCCESS.
1069     */
1070    @Test
1071    public void testGetSsid_failure() throws Exception {
1072        executeAndValidateInitializationSequence(false, false, false);
1073
1074        doAnswer(new AnswerWithArguments() {
1075            public void answer(byte[] address, ISupplicantP2pIface.getSsidCallback cb) {
1076                cb.onValues(mStatusFailure, null);
1077            }
1078        })
1079        .when(mISupplicantP2pIfaceMock).getSsid(
1080                any(byte[].class), any(ISupplicantP2pIface.getSsidCallback.class));
1081
1082        assertNull(mDut.getSsid(mPeerMacAddress));
1083        // Check that service is still alive.
1084        assertTrue(mDut.isInitializationComplete());
1085    }
1086
1087    /**
1088     * Verify that getSsid disconnects and returns false, if HAL throws exception.
1089     */
1090    @Test
1091    public void testGetSsid_exception() throws Exception {
1092        executeAndValidateInitializationSequence(false, false, false);
1093        doThrow(mRemoteException)
1094        .when(mISupplicantP2pIfaceMock).getSsid(
1095                any(byte[].class), any(ISupplicantP2pIface.getSsidCallback.class));
1096
1097        assertNull(mDut.getSsid(mPeerMacAddress));
1098        // Check service is dead.
1099        assertFalse(mDut.isInitializationComplete());
1100    }
1101
1102
1103    /**
1104     * Sunny day scenario for reinvoke()
1105     */
1106    @Test
1107    public void testReinvoke_success() throws Exception {
1108        when(mISupplicantP2pIfaceMock.reinvoke(anyInt(), eq(mPeerMacAddressBytes)))
1109                .thenReturn(mStatusSuccess);
1110        // Default value when service is not initialized.
1111        assertFalse(mDut.reinvoke(0, mPeerMacAddress));
1112        executeAndValidateInitializationSequence(false, false, false);
1113        assertTrue(mDut.reinvoke(0, mPeerMacAddress));
1114    }
1115
1116    /**
1117     * Reinvoke with invalid arguments.
1118     */
1119    @Test
1120    public void testReinvoke_invalidArguments() throws Exception {
1121        executeAndValidateInitializationSequence(false, false, false);
1122        when(mISupplicantP2pIfaceMock.reinvoke(anyInt(), any(byte[].class)))
1123                .thenReturn(mStatusSuccess);
1124
1125        for (String address : mInvalidMacAddresses) {
1126            assertFalse(mDut.reinvoke(0, address));
1127        }
1128    }
1129
1130    /**
1131     * Verify that reinvoke returns false, if status is not SUCCESS.
1132     */
1133    @Test
1134    public void testReinvoke_failure() throws Exception {
1135        executeAndValidateInitializationSequence(false, false, false);
1136        when(mISupplicantP2pIfaceMock.reinvoke(anyInt(), any(byte[].class)))
1137                .thenReturn(mStatusFailure);
1138        assertFalse(mDut.reinvoke(0, mPeerMacAddress));
1139        // Check that service is still alive.
1140        assertTrue(mDut.isInitializationComplete());
1141    }
1142
1143    /**
1144     * Verify that reinvoke disconnects and returns false, if HAL throws exception.
1145     */
1146    @Test
1147    public void testReinvoke_exception() throws Exception {
1148        executeAndValidateInitializationSequence(false, false, false);
1149        when(mISupplicantP2pIfaceMock.reinvoke(anyInt(), any(byte[].class)))
1150                .thenThrow(mRemoteException);
1151        assertFalse(mDut.reinvoke(0, mPeerMacAddress));
1152        // Check service is dead.
1153        assertFalse(mDut.isInitializationComplete());
1154    }
1155
1156
1157    /**
1158     * Sunny day scenario for groupAdd()
1159     */
1160    @Test
1161    public void testGroupAdd_success() throws Exception {
1162        when(mISupplicantP2pIfaceMock.addGroup(eq(true), eq(3)))
1163                .thenReturn(mStatusSuccess);
1164        // Default value when service is not initialized.
1165        assertFalse(mDut.groupAdd(3, true));
1166        executeAndValidateInitializationSequence(false, false, false);
1167        assertTrue(mDut.groupAdd(3, true));
1168    }
1169
1170    /**
1171     * Verify that groupAdd returns false, if status is not SUCCESS.
1172     */
1173    @Test
1174    public void testGroupAdd_failure() throws Exception {
1175        executeAndValidateInitializationSequence(false, false, false);
1176        when(mISupplicantP2pIfaceMock.addGroup(anyBoolean(), anyInt()))
1177                .thenReturn(mStatusFailure);
1178        assertFalse(mDut.groupAdd(0, true));
1179        // Check that service is still alive.
1180        assertTrue(mDut.isInitializationComplete());
1181    }
1182
1183    /**
1184     * Verify that groupAdd disconnects and returns false, if HAL throws exception.
1185     */
1186    @Test
1187    public void testGroupAdd_exception() throws Exception {
1188        executeAndValidateInitializationSequence(false, false, false);
1189        when(mISupplicantP2pIfaceMock.addGroup(anyBoolean(), anyInt()))
1190                .thenThrow(mRemoteException);
1191        assertFalse(mDut.groupAdd(0, true));
1192        // Check service is dead.
1193        assertFalse(mDut.isInitializationComplete());
1194    }
1195
1196
1197    /**
1198     * Sunny day scenario for groupRemove()
1199     */
1200    @Test
1201    public void testGroupRemove_success() throws Exception {
1202        when(mISupplicantP2pIfaceMock.removeGroup(eq(mIfaceName)))
1203                .thenReturn(mStatusSuccess);
1204        // Default value when service is not initialized.
1205        assertFalse(mDut.groupRemove(mIfaceName));
1206        executeAndValidateInitializationSequence(false, false, false);
1207        assertTrue(mDut.groupRemove(mIfaceName));
1208    }
1209
1210    /**
1211     * Verify that groupRemove returns false, if status is not SUCCESS.
1212     */
1213    @Test
1214    public void testGroupRemove_failure() throws Exception {
1215        executeAndValidateInitializationSequence(false, false, false);
1216        when(mISupplicantP2pIfaceMock.removeGroup(anyString()))
1217                .thenReturn(mStatusFailure);
1218        assertFalse(mDut.groupRemove(mIfaceName));
1219        // Check that service is still alive.
1220        assertTrue(mDut.isInitializationComplete());
1221    }
1222
1223    /**
1224     * Verify that groupRemove disconnects and returns false, if HAL throws exception.
1225     */
1226    @Test
1227    public void testGroupRemove_exception() throws Exception {
1228        executeAndValidateInitializationSequence(false, false, false);
1229        when(mISupplicantP2pIfaceMock.removeGroup(anyString()))
1230                .thenThrow(mRemoteException);
1231        assertFalse(mDut.groupRemove(mIfaceName));
1232        // Check service is dead.
1233        assertFalse(mDut.isInitializationComplete());
1234    }
1235
1236
1237    /**
1238     * Sunny day scenario for getGroupCapability()
1239     */
1240    @Test
1241    public void testGetGroupCapability_success() throws Exception {
1242        final int caps = 123;
1243
1244        doAnswer(new AnswerWithArguments() {
1245            public void answer(byte[] address, ISupplicantP2pIface.getGroupCapabilityCallback cb) {
1246                cb.onValues(mStatusSuccess, caps);
1247            }
1248        })
1249        .when(mISupplicantP2pIfaceMock)
1250                .getGroupCapability(
1251                        eq(mPeerMacAddressBytes),
1252                        any(ISupplicantP2pIface.getGroupCapabilityCallback.class));
1253
1254        // Default value when service is not initialized.
1255        assertEquals(-1, mDut.getGroupCapability(mPeerMacAddress));
1256        executeAndValidateInitializationSequence(false, false, false);
1257        assertEquals(caps, mDut.getGroupCapability(mPeerMacAddress));
1258    }
1259
1260    /**
1261     * GetGroupCapability with invalid arguments.
1262     */
1263    @Test
1264    public void testGetGroupCapability_invalidArguments() throws Exception {
1265        executeAndValidateInitializationSequence(false, false, false);
1266
1267        doAnswer(new AnswerWithArguments() {
1268            public void answer(byte[] address, ISupplicantP2pIface.getGroupCapabilityCallback cb) {
1269                cb.onValues(mStatusSuccess, 0);
1270            }
1271        })
1272        .when(mISupplicantP2pIfaceMock)
1273                .getGroupCapability(
1274                        eq(mPeerMacAddressBytes),
1275                        any(ISupplicantP2pIface.getGroupCapabilityCallback.class));
1276
1277        for (String address : mInvalidMacAddresses) {
1278            assertEquals(-1, mDut.getGroupCapability(address));
1279        }
1280    }
1281
1282    /**
1283     * Verify that getGroupCapability returns false, if status is not SUCCESS.
1284     */
1285    @Test
1286    public void testGetGroupCapability_failure() throws Exception {
1287        executeAndValidateInitializationSequence(false, false, false);
1288
1289        doAnswer(new AnswerWithArguments() {
1290            public void answer(byte[] address, ISupplicantP2pIface.getGroupCapabilityCallback cb) {
1291                cb.onValues(mStatusFailure, 0);
1292            }
1293        })
1294        .when(mISupplicantP2pIfaceMock)
1295                .getGroupCapability(
1296                        eq(mPeerMacAddressBytes),
1297                        any(ISupplicantP2pIface.getGroupCapabilityCallback.class));
1298
1299        assertEquals(-1, mDut.getGroupCapability(mPeerMacAddress));
1300        // Check that service is still alive.
1301        assertTrue(mDut.isInitializationComplete());
1302    }
1303
1304    /**
1305     * Verify that getGroupCapability disconnects and returns false, if HAL throws exception.
1306     */
1307    @Test
1308    public void testGetGroupCapability_exception() throws Exception {
1309        executeAndValidateInitializationSequence(false, false, false);
1310        doThrow(mRemoteException)
1311                .when(mISupplicantP2pIfaceMock)
1312                .getGroupCapability(
1313                        eq(mPeerMacAddressBytes),
1314                        any(ISupplicantP2pIface.getGroupCapabilityCallback.class));
1315        assertEquals(-1, mDut.getGroupCapability(mPeerMacAddress));
1316        // Check service is dead.
1317        assertFalse(mDut.isInitializationComplete());
1318    }
1319
1320
1321    /**
1322     * Sunny day scenario for configureExtListen()
1323     */
1324    @Test
1325    public void testConfigureExtListen_success() throws Exception {
1326        when(mISupplicantP2pIfaceMock.configureExtListen(eq(123), eq(456)))
1327                .thenReturn(mStatusSuccess);
1328        when(mISupplicantP2pIfaceMock.configureExtListen(eq(0), eq(0)))
1329                .thenReturn(mStatusSuccess);
1330        // Default value when service is not initialized.
1331        assertFalse(mDut.configureExtListen(true, 123, 456));
1332        executeAndValidateInitializationSequence(false, false, false);
1333        assertTrue(mDut.configureExtListen(true, 123, 456));
1334        // Turning listening off should reset intervals to 0s.
1335        assertTrue(mDut.configureExtListen(false, 999, 999));
1336        // Disable listening.
1337        assertTrue(mDut.configureExtListen(false, -1, -1));
1338    }
1339
1340    /**
1341     * Test configureExtListen with invalid parameters.
1342     */
1343    @Test
1344    public void testConfigureExtListen_invalidArguments() throws Exception {
1345        executeAndValidateInitializationSequence(false, false, false);
1346        when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
1347                .thenReturn(mStatusFailure);
1348        assertFalse(mDut.configureExtListen(true, -1, 1));
1349        assertFalse(mDut.configureExtListen(true, 1, -1));
1350    }
1351
1352    /**
1353     * Verify that configureExtListen returns false, if status is not SUCCESS.
1354     */
1355    @Test
1356    public void testConfigureExtListen_failure() throws Exception {
1357        executeAndValidateInitializationSequence(false, false, false);
1358        when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
1359                .thenReturn(mStatusFailure);
1360        assertFalse(mDut.configureExtListen(true, 1, 1));
1361        // Check that service is still alive.
1362        assertTrue(mDut.isInitializationComplete());
1363    }
1364
1365    /**
1366     * Verify that configureExtListen disconnects and returns false, if HAL throws exception.
1367     */
1368    @Test
1369    public void testConfigureExtListen_exception() throws Exception {
1370        executeAndValidateInitializationSequence(false, false, false);
1371        when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
1372                .thenThrow(mRemoteException);
1373        assertFalse(mDut.configureExtListen(true, 1, 1));
1374        // Check service is dead.
1375        assertFalse(mDut.isInitializationComplete());
1376    }
1377
1378
1379    /**
1380     * Sunny day scenario for setListenChannel()
1381     */
1382    @Test
1383    public void testSetListenChannel_success() throws Exception {
1384        int lc = 4;
1385        int oc = 163;
1386        ISupplicantP2pIface.FreqRange range1 = new ISupplicantP2pIface.FreqRange();
1387        range1.min = 1000;
1388        range1.max = 5810;
1389        ISupplicantP2pIface.FreqRange range2 = new ISupplicantP2pIface.FreqRange();
1390        range2.min = 5820;
1391        range2.max = 6000;
1392        ArrayList<ISupplicantP2pIface.FreqRange> ranges = new ArrayList<>();
1393        ranges.add(range1);
1394        ranges.add(range2);
1395
1396        when(mISupplicantP2pIfaceMock.setListenChannel(eq(lc),  anyInt()))
1397                .thenReturn(mStatusSuccess);
1398        when(mISupplicantP2pIfaceMock.setDisallowedFrequencies(eq(ranges)))
1399                .thenReturn(mStatusSuccess);
1400        // Default value when service is not initialized.
1401        assertFalse(mDut.setListenChannel(lc, oc));
1402        executeAndValidateInitializationSequence(false, false, false);
1403        assertTrue(mDut.setListenChannel(lc, oc));
1404    }
1405
1406    /**
1407     * Sunny day scenario for setListenChannel()
1408     */
1409    @Test
1410    public void testSetListenChannel_successResetDisallowedFreq() throws Exception {
1411        int lc = 2;
1412        int oc = 0;
1413        ArrayList<ISupplicantP2pIface.FreqRange> ranges = new ArrayList<>();
1414
1415        when(mISupplicantP2pIfaceMock.setListenChannel(eq(lc),  anyInt()))
1416                .thenReturn(mStatusSuccess);
1417        when(mISupplicantP2pIfaceMock.setDisallowedFrequencies(eq(ranges)))
1418                .thenReturn(mStatusSuccess);
1419        // Default value when service is not initialized.
1420        assertFalse(mDut.setListenChannel(lc, oc));
1421        executeAndValidateInitializationSequence(false, false, false);
1422        assertTrue(mDut.setListenChannel(lc, oc));
1423    }
1424
1425    /**
1426     * Test setListenChannel with invalid parameters.
1427     */
1428    @Test
1429    public void testSetListenChannel_invalidArguments() throws Exception {
1430        executeAndValidateInitializationSequence(false, false, false);
1431        when(mISupplicantP2pIfaceMock.setListenChannel(anyInt(), anyInt()))
1432                .thenReturn(mStatusSuccess);
1433        when(mISupplicantP2pIfaceMock.setDisallowedFrequencies(any(ArrayList.class)))
1434                .thenReturn(mStatusSuccess);
1435        assertFalse(mDut.setListenChannel(-1, 1));
1436        assertFalse(mDut.setListenChannel(1, -1));
1437    }
1438
1439    /**
1440     * Verify that setListenChannel returns false, if status is not SUCCESS.
1441     */
1442    @Test
1443    public void testSetListenChannel_failure() throws Exception {
1444        executeAndValidateInitializationSequence(false, false, false);
1445        when(mISupplicantP2pIfaceMock.setListenChannel(anyInt(), anyInt()))
1446                .thenReturn(mStatusFailure);
1447        when(mISupplicantP2pIfaceMock.setDisallowedFrequencies(any(ArrayList.class)))
1448                .thenReturn(mStatusSuccess);
1449        assertFalse(mDut.setListenChannel(1, 1));
1450        // Check that service is still alive.
1451        assertTrue(mDut.isInitializationComplete());
1452    }
1453
1454    /**
1455     * Verify that setListenChannel disconnects and returns false, if HAL throws exception.
1456     */
1457    @Test
1458    public void testSetListenChannel_exception() throws Exception {
1459        executeAndValidateInitializationSequence(false, false, false);
1460        when(mISupplicantP2pIfaceMock.setListenChannel(anyInt(), anyInt()))
1461                .thenThrow(mRemoteException);
1462        assertFalse(mDut.setListenChannel(1, 1));
1463        // Check service is dead.
1464        assertFalse(mDut.isInitializationComplete());
1465    }
1466
1467
1468    /**
1469     * Sunny day scenario for serviceAdd()
1470     */
1471    @Test
1472    public void testServiceAdd_success() throws Exception {
1473        WifiP2pServiceInfo info = createDummyP2pServiceInfo(
1474                mValidUpnpService, mValidBonjourService);
1475        final HashSet<String> services = new HashSet<String>();
1476
1477        doAnswer(new AnswerWithArguments() {
1478            public SupplicantStatus answer(int version, String name) {
1479                services.add("upnp");
1480                assertEquals(mValidUpnpServiceVersion, version);
1481                assertEquals(mValidUpnpServiceName, name);
1482                return mStatusSuccess;
1483            }
1484        })
1485        .when(mISupplicantP2pIfaceMock).addUpnpService(anyInt(), anyString());
1486
1487        doAnswer(new AnswerWithArguments() {
1488            public SupplicantStatus answer(ArrayList<Byte> request, ArrayList<Byte> response) {
1489                services.add("bonjour");
1490                assertEquals(mValidBonjourServiceRequest, request);
1491                assertEquals(mValidBonjourServiceResponse, response);
1492                return mStatusSuccess;
1493            }
1494        })
1495        .when(mISupplicantP2pIfaceMock).addBonjourService(
1496                any(ArrayList.class), any(ArrayList.class));
1497
1498        // Default value when service is not initialized.
1499        assertFalse(mDut.serviceAdd(info));
1500        executeAndValidateInitializationSequence(false, false, false);
1501        assertTrue(mDut.serviceAdd(info));
1502        // Confirm that both services have been added.
1503        assertTrue(services.contains("upnp"));
1504        assertTrue(services.contains("bonjour"));
1505
1506        // Empty services should cause no trouble.
1507        assertTrue(mDut.serviceAdd(createDummyP2pServiceInfo()));
1508    }
1509
1510    /**
1511     * Test serviceAdd with invalid parameters.
1512     */
1513    @Test
1514    public void testServiceAdd_invalidArguments() throws Exception {
1515        executeAndValidateInitializationSequence(false, false, false);
1516
1517        when(mISupplicantP2pIfaceMock.addUpnpService(anyInt(), anyString()))
1518                .thenReturn(mStatusSuccess);
1519        when(mISupplicantP2pIfaceMock.addBonjourService(
1520                any(ArrayList.class), any(ArrayList.class)))
1521                .thenReturn(mStatusSuccess);
1522
1523        assertFalse(mDut.serviceAdd(null));
1524        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidService1)));
1525        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidService2)));
1526        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidUpnpService1)));
1527        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidUpnpService2)));
1528        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidUpnpService3)));
1529        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidBonjourService1)));
1530        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidBonjourService2)));
1531        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidBonjourService3)));
1532        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mInvalidBonjourService4)));
1533    }
1534
1535    /**
1536     * Verify that serviceAdd returns false, if status is not SUCCESS.
1537     */
1538    @Test
1539    public void testServiceAdd_failure() throws Exception {
1540        executeAndValidateInitializationSequence(false, false, false);
1541
1542        when(mISupplicantP2pIfaceMock.addUpnpService(anyInt(), anyString()))
1543                .thenReturn(mStatusFailure);
1544        when(mISupplicantP2pIfaceMock.addBonjourService(
1545                any(ArrayList.class), any(ArrayList.class)))
1546                .thenReturn(mStatusFailure);
1547
1548        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mValidUpnpService)));
1549        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mValidBonjourService)));
1550
1551        // Check that service is still alive.
1552        assertTrue(mDut.isInitializationComplete());
1553    }
1554
1555    /**
1556     * Verify that serviceAdd disconnects and returns false, if HAL throws exception.
1557     */
1558    @Test
1559    public void testServiceAdd_exception() throws Exception {
1560        executeAndValidateInitializationSequence(false, false, false);
1561
1562        when(mISupplicantP2pIfaceMock.addUpnpService(anyInt(), anyString()))
1563                .thenThrow(mRemoteException);
1564        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mValidUpnpService)));
1565        // Check service is dead.
1566        assertFalse(mDut.isInitializationComplete());
1567
1568        executeAndValidateInitializationSequence(false, false, false);
1569        when(mISupplicantP2pIfaceMock.addBonjourService(
1570                any(ArrayList.class), any(ArrayList.class)))
1571                .thenThrow(mRemoteException);
1572        assertFalse(mDut.serviceAdd(createDummyP2pServiceInfo(mValidBonjourService)));
1573        // Check service is dead.
1574        assertFalse(mDut.isInitializationComplete());
1575    }
1576
1577
1578    /**
1579     * Sunny day scenario for serviceRemove()
1580     */
1581    @Test
1582    public void testServiceRemove_success() throws Exception {
1583        WifiP2pServiceInfo info = createDummyP2pServiceInfo(
1584                mValidUpnpService, mValidBonjourService);
1585        final HashSet<String> services = new HashSet<String>();
1586
1587        doAnswer(new AnswerWithArguments() {
1588            public SupplicantStatus answer(int version, String name) {
1589                services.add("upnp");
1590                assertEquals(mValidUpnpServiceVersion, version);
1591                assertEquals(mValidUpnpServiceName, name);
1592                return mStatusSuccess;
1593            }
1594        })
1595        .when(mISupplicantP2pIfaceMock).removeUpnpService(anyInt(), anyString());
1596
1597        doAnswer(new AnswerWithArguments() {
1598            public SupplicantStatus answer(ArrayList<Byte> request) {
1599                services.add("bonjour");
1600                assertEquals(mValidBonjourServiceRequest, request);
1601                return mStatusSuccess;
1602            }
1603        })
1604        .when(mISupplicantP2pIfaceMock).removeBonjourService(any(ArrayList.class));
1605
1606        // Default value when service is not initialized.
1607        assertFalse(mDut.serviceRemove(info));
1608        executeAndValidateInitializationSequence(false, false, false);
1609        assertTrue(mDut.serviceRemove(info));
1610        // Confirm that both services have been removed.
1611        assertTrue(services.contains("upnp"));
1612        assertTrue(services.contains("bonjour"));
1613
1614        // Empty services should cause no trouble.
1615        assertTrue(mDut.serviceRemove(createDummyP2pServiceInfo()));
1616    }
1617
1618    /**
1619     * Test serviceRemove with invalid parameters.
1620     */
1621    @Test
1622    public void testServiceRemove_invalidArguments() throws Exception {
1623        executeAndValidateInitializationSequence(false, false, false);
1624
1625        when(mISupplicantP2pIfaceMock.removeUpnpService(anyInt(), anyString()))
1626                .thenReturn(mStatusSuccess);
1627        when(mISupplicantP2pIfaceMock.removeBonjourService(any(ArrayList.class)))
1628                .thenReturn(mStatusSuccess);
1629
1630        assertFalse(mDut.serviceRemove(null));
1631        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidService1)));
1632        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidService2)));
1633        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidUpnpService1)));
1634        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidUpnpService2)));
1635        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidUpnpService3)));
1636        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidBonjourService1)));
1637        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidBonjourService2)));
1638        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidBonjourService3)));
1639        // Response parameter is ignored by serviceRemove call, hence the following would pass.
1640        // The production code would need to parse otherwise redundant parameter to fail on this
1641        // one.
1642        //
1643        // assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mInvalidBonjourService4)));
1644    }
1645
1646    /**
1647     * Verify that serviceRemove returns false, if status is not SUCCESS.
1648     */
1649    @Test
1650    public void testServiceRemove_failure() throws Exception {
1651        executeAndValidateInitializationSequence(false, false, false);
1652
1653        when(mISupplicantP2pIfaceMock.removeUpnpService(anyInt(), anyString()))
1654                .thenReturn(mStatusFailure);
1655        when(mISupplicantP2pIfaceMock.removeBonjourService(any(ArrayList.class)))
1656                .thenReturn(mStatusFailure);
1657
1658        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mValidUpnpService)));
1659        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mValidBonjourService)));
1660
1661        // Check that service is still alive.
1662        assertTrue(mDut.isInitializationComplete());
1663    }
1664
1665    /**
1666     * Verify that serviceRemove disconnects and returns false, if HAL throws exception.
1667     */
1668    @Test
1669    public void testServiceRemove_exception() throws Exception {
1670        executeAndValidateInitializationSequence(false, false, false);
1671
1672        when(mISupplicantP2pIfaceMock.removeUpnpService(anyInt(), anyString()))
1673                .thenThrow(mRemoteException);
1674        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mValidUpnpService)));
1675        // Check service is dead.
1676        assertFalse(mDut.isInitializationComplete());
1677
1678        executeAndValidateInitializationSequence(false, false, false);
1679        when(mISupplicantP2pIfaceMock.removeBonjourService(any(ArrayList.class)))
1680                .thenThrow(mRemoteException);
1681        assertFalse(mDut.serviceRemove(createDummyP2pServiceInfo(mValidBonjourService)));
1682        // Check service is dead.
1683        assertFalse(mDut.isInitializationComplete());
1684    }
1685
1686
1687    /**
1688     * Sunny day scenario for requestServiceDiscovery()
1689     */
1690    @Test
1691    public void testRequestServiceDiscovery_success() throws Exception {
1692        final int caps = 123;
1693
1694        doAnswer(new AnswerWithArguments() {
1695            public void answer(byte[] address, ArrayList<Byte> query,
1696                    ISupplicantP2pIface.requestServiceDiscoveryCallback cb) {
1697                cb.onValues(mStatusSuccess, 1234);
1698            }
1699        })
1700        .when(mISupplicantP2pIfaceMock)
1701                .requestServiceDiscovery(
1702                        eq(mPeerMacAddressBytes),
1703                        eq(mValidBonjourServiceRequest),
1704                        any(ISupplicantP2pIface.requestServiceDiscoveryCallback.class));
1705
1706        // Default value when service is not initialized.
1707        assertNull(mDut.requestServiceDiscovery(mPeerMacAddress, mValidServiceRequestString));
1708
1709        executeAndValidateInitializationSequence(false, false, false);
1710        assertEquals("1234", mDut.requestServiceDiscovery(
1711                mPeerMacAddress, mValidServiceRequestString));
1712    }
1713
1714    /**
1715     * RequestServiceDiscovery with invalid arguments.
1716     */
1717    @Test
1718    public void testRequestServiceDiscovery_invalidArguments() throws Exception {
1719        executeAndValidateInitializationSequence(false, false, false);
1720
1721        doAnswer(new AnswerWithArguments() {
1722            public void answer(byte[] address, ArrayList<Byte> query,
1723                    ISupplicantP2pIface.requestServiceDiscoveryCallback cb) {
1724                cb.onValues(mStatusSuccess, 0);
1725            }
1726        })
1727        .when(mISupplicantP2pIfaceMock)
1728                .requestServiceDiscovery(
1729                        any(byte[].class), any(ArrayList.class),
1730                        any(ISupplicantP2pIface.requestServiceDiscoveryCallback.class));
1731
1732        for (String address : mInvalidMacAddresses) {
1733            assertNull(mDut.requestServiceDiscovery(
1734                    address, mValidServiceRequestString));
1735        }
1736        assertNull(mDut.requestServiceDiscovery(mPeerMacAddress, null));
1737        assertNull(mDut.requestServiceDiscovery(mPeerMacAddress, mInvalidServiceRequestString));
1738    }
1739
1740    /**
1741     * Verify that requestServiceDiscovery returns false, if status is not SUCCESS.
1742     */
1743    @Test
1744    public void testRequestServiceDiscovery_failure() throws Exception {
1745        executeAndValidateInitializationSequence(false, false, false);
1746
1747        doAnswer(new AnswerWithArguments() {
1748            public void answer(
1749                    byte[] address, ArrayList<Byte> query,
1750                    ISupplicantP2pIface.requestServiceDiscoveryCallback cb) {
1751                cb.onValues(mStatusFailure, 0);
1752            }
1753        })
1754        .when(mISupplicantP2pIfaceMock)
1755                .requestServiceDiscovery(
1756                        any(byte[].class), any(ArrayList.class),
1757                        any(ISupplicantP2pIface.requestServiceDiscoveryCallback.class));
1758
1759        assertNull(mDut.requestServiceDiscovery(mPeerMacAddress, mValidServiceRequestString));
1760        // Check that service is still alive.
1761        assertTrue(mDut.isInitializationComplete());
1762    }
1763
1764    /**
1765     * Verify that requestServiceDiscovery disconnects and returns false, if HAL throws exception.
1766     */
1767    @Test
1768    public void testRequestServiceDiscovery_exception() throws Exception {
1769        executeAndValidateInitializationSequence(false, false, false);
1770        doThrow(mRemoteException)
1771                .when(mISupplicantP2pIfaceMock)
1772                .requestServiceDiscovery(
1773                        any(byte[].class), any(ArrayList.class),
1774                        any(ISupplicantP2pIface.requestServiceDiscoveryCallback.class));
1775        assertNull(mDut.requestServiceDiscovery(mPeerMacAddress, mValidServiceRequestString));
1776        // Check service is dead.
1777        assertFalse(mDut.isInitializationComplete());
1778    }
1779
1780    // Test constant used in cancelServiceDiscovery tests
1781    static final String SERVICE_IDENTIFIER_STR = "521918410304";
1782    static final long SERVICE_IDENTIFIER_LONG = 521918410304L;
1783
1784    /**
1785     * Sunny day scenario for cancelServiceDiscovery()
1786     */
1787    @Test
1788    public void testCancelServiceDiscovery_success() throws Exception {
1789        when(mISupplicantP2pIfaceMock.cancelServiceDiscovery(SERVICE_IDENTIFIER_LONG))
1790                .thenReturn(mStatusSuccess);
1791        // Default value when service is not initialized.
1792        assertFalse(mDut.cancelServiceDiscovery(SERVICE_IDENTIFIER_STR));
1793        executeAndValidateInitializationSequence(false, false, false);
1794        assertTrue(mDut.cancelServiceDiscovery(SERVICE_IDENTIFIER_STR));
1795    }
1796
1797    /**
1798     * Test cancelServiceDiscovery with invalid parameters.
1799     */
1800    @Test
1801    public void testCancelServiceDiscovery_invalidArguments() throws Exception {
1802        executeAndValidateInitializationSequence(false, false, false);
1803        when(mISupplicantP2pIfaceMock.cancelServiceDiscovery(anyLong()))
1804                .thenReturn(mStatusFailure);
1805        assertFalse(mDut.cancelServiceDiscovery(null));
1806        assertFalse(mDut.cancelServiceDiscovery("not a number"));
1807    }
1808
1809    /**
1810     * Verify that cancelServiceDiscovery returns false, if status is not SUCCESS.
1811     */
1812    @Test
1813    public void testCancelServiceDiscovery_failure() throws Exception {
1814        executeAndValidateInitializationSequence(false, false, false);
1815        when(mISupplicantP2pIfaceMock.cancelServiceDiscovery(anyLong()))
1816                .thenReturn(mStatusFailure);
1817        assertFalse(mDut.cancelServiceDiscovery(SERVICE_IDENTIFIER_STR));
1818        // Check that service is still alive.
1819        assertTrue(mDut.isInitializationComplete());
1820    }
1821
1822    /**
1823     * Verify that cancelServiceDiscovery disconnects and returns false, if HAL throws exception.
1824     */
1825    @Test
1826    public void testCancelServiceDiscovery_exception() throws Exception {
1827        executeAndValidateInitializationSequence(false, false, false);
1828        when(mISupplicantP2pIfaceMock.cancelServiceDiscovery(anyLong()))
1829                .thenThrow(mRemoteException);
1830        assertFalse(mDut.cancelServiceDiscovery(SERVICE_IDENTIFIER_STR));
1831        // Check service is dead.
1832        assertFalse(mDut.isInitializationComplete());
1833    }
1834
1835
1836    /**
1837     * Sunny day scenario for setMiracastMode()
1838     */
1839    @Test
1840    public void testSetMiracastMode_success() throws Exception {
1841        HashSet<Byte> modes = new HashSet<Byte>();
1842
1843        when(mISupplicantP2pIfaceMock.setMiracastMode(anyByte()))
1844                .thenAnswer(new AnswerWithArguments() {
1845                    public SupplicantStatus answer(byte mode) {
1846                        modes.add(mode);
1847                        return mStatusSuccess;
1848                    }
1849                });
1850        // Default value when service is not initialized.
1851        assertFalse(mDut.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE));
1852        executeAndValidateInitializationSequence(false, false, false);
1853        assertTrue(mDut.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE));
1854        assertTrue(modes.contains(ISupplicantP2pIface.MiracastMode.SOURCE));
1855
1856        assertTrue(mDut.setMiracastMode(WifiP2pManager.MIRACAST_SINK));
1857        assertTrue(modes.contains(ISupplicantP2pIface.MiracastMode.SINK));
1858
1859        // Any invalid number yields disabled miracast mode.
1860        assertTrue(mDut.setMiracastMode(-1));
1861        assertTrue(modes.contains(ISupplicantP2pIface.MiracastMode.DISABLED));
1862    }
1863
1864    /**
1865     * Verify that setMiracastMode returns false, if status is not SUCCESS.
1866     */
1867    @Test
1868    public void testSetMiracastMode_failure() throws Exception {
1869        executeAndValidateInitializationSequence(false, false, false);
1870        when(mISupplicantP2pIfaceMock.setMiracastMode(anyByte()))
1871                .thenReturn(mStatusFailure);
1872        assertFalse(mDut.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE));
1873        // Check that service is still alive.
1874        assertTrue(mDut.isInitializationComplete());
1875    }
1876
1877    /**
1878     * Verify that setMiracastMode disconnects and returns false, if HAL throws exception.
1879     */
1880    @Test
1881    public void testSetMiracastMode_exception() throws Exception {
1882        executeAndValidateInitializationSequence(false, false, false);
1883        when(mISupplicantP2pIfaceMock.setMiracastMode(anyByte()))
1884                .thenThrow(mRemoteException);
1885        assertFalse(mDut.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE));
1886        // Check service is dead.
1887        assertFalse(mDut.isInitializationComplete());
1888    }
1889
1890
1891    /**
1892     * Sunny day scenario for startWpsPbc()
1893     */
1894    @Test
1895    public void testStartWpsPbc_success() throws Exception {
1896        when(mISupplicantP2pIfaceMock.startWpsPbc(eq(mIfaceName), eq(mPeerMacAddressBytes)))
1897                .thenReturn(mStatusSuccess);
1898        // Default value when service is not initialized.
1899        assertFalse(mDut.startWpsPbc(mIfaceName, mPeerMacAddress));
1900        executeAndValidateInitializationSequence(false, false, false);
1901        assertTrue(mDut.startWpsPbc(mIfaceName, mPeerMacAddress));
1902    }
1903
1904    /**
1905     * StartWpsPbc with invalid arguments.
1906     */
1907    @Test
1908    public void testStartWpsPbc_invalidArguments() throws Exception {
1909        executeAndValidateInitializationSequence(false, false, false);
1910        when(mISupplicantP2pIfaceMock.startWpsPbc(anyString(), any(byte[].class)))
1911                .thenReturn(mStatusSuccess);
1912
1913        for (String address : mInvalidMacAddresses) {
1914            assertFalse(mDut.startWpsPbc(mIfaceName, address));
1915        }
1916
1917        assertFalse(mDut.startWpsPbc(null, mPeerMacAddress));
1918    }
1919
1920    /**
1921     * Verify that startWpsPbc returns false, if status is not SUCCESS.
1922     */
1923    @Test
1924    public void testStartWpsPbc_failure() throws Exception {
1925        executeAndValidateInitializationSequence(false, false, false);
1926        when(mISupplicantP2pIfaceMock.startWpsPbc(anyString(), any(byte[].class)))
1927                .thenReturn(mStatusFailure);
1928        assertFalse(mDut.startWpsPbc(mIfaceName, mPeerMacAddress));
1929        // Check that service is still alive.
1930        assertTrue(mDut.isInitializationComplete());
1931    }
1932
1933    /**
1934     * Verify that startWpsPbc disconnects and returns false, if HAL throws exception.
1935     */
1936    @Test
1937    public void testStartWpsPbc_exception() throws Exception {
1938        executeAndValidateInitializationSequence(false, false, false);
1939        when(mISupplicantP2pIfaceMock.startWpsPbc(anyString(), any(byte[].class)))
1940                .thenThrow(mRemoteException);
1941        assertFalse(mDut.startWpsPbc(mIfaceName, mPeerMacAddress));
1942        // Check service is dead.
1943        assertFalse(mDut.isInitializationComplete());
1944    }
1945
1946
1947    /**
1948     * Sunny day scenario for startWpsPinKeypad()
1949     */
1950    @Test
1951    public void testStartWpsPinKeypad_success() throws Exception {
1952        when(mISupplicantP2pIfaceMock.startWpsPinKeypad(eq(mIfaceName), eq("1234")))
1953                .thenReturn(mStatusSuccess);
1954        // Default value when service is not initialized.
1955        assertFalse(mDut.startWpsPinKeypad(mIfaceName, "1234"));
1956        executeAndValidateInitializationSequence(false, false, false);
1957        assertTrue(mDut.startWpsPinKeypad(mIfaceName, "1234"));
1958    }
1959
1960    /**
1961     * StartWpsPinKeypad with invalid arguments.
1962     */
1963    @Test
1964    public void testStartWpsPinKeypad_invalidArguments() throws Exception {
1965        executeAndValidateInitializationSequence(false, false, false);
1966        when(mISupplicantP2pIfaceMock.startWpsPinKeypad(anyString(), anyString()))
1967                .thenReturn(mStatusSuccess);
1968
1969        assertFalse(mDut.startWpsPinKeypad(null, "1234"));
1970        assertFalse(mDut.startWpsPinKeypad(mIfaceName, null));
1971        // StartWpsPinPinKeypad does not validate, that PIN indeed holds an integer encoded in a
1972        // string. This code would be redundant, as HAL requires string to be passed.
1973    }
1974
1975    /**
1976     * Verify that startWpsPinKeypad returns false, if status is not SUCCESS.
1977     */
1978    @Test
1979    public void testStartWpsPinKeypad_failure() throws Exception {
1980        executeAndValidateInitializationSequence(false, false, false);
1981        when(mISupplicantP2pIfaceMock.startWpsPinKeypad(anyString(), anyString()))
1982                .thenReturn(mStatusFailure);
1983        assertFalse(mDut.startWpsPinKeypad(mIfaceName, "1234"));
1984        // Check that service is still alive.
1985        assertTrue(mDut.isInitializationComplete());
1986    }
1987
1988    /**
1989     * Verify that startWpsPinKeypad disconnects and returns false, if HAL throws exception.
1990     */
1991    @Test
1992    public void testStartWpsPinKeypad_exception() throws Exception {
1993        executeAndValidateInitializationSequence(false, false, false);
1994        when(mISupplicantP2pIfaceMock.startWpsPinKeypad(anyString(), anyString()))
1995                .thenThrow(mRemoteException);
1996        assertFalse(mDut.startWpsPinKeypad(mIfaceName, "1234"));
1997        // Check service is dead.
1998        assertFalse(mDut.isInitializationComplete());
1999    }
2000
2001
2002    /**
2003     * Sunny day scenario for startWpsPinDisplay()
2004     */
2005    @Test
2006    public void testStartWpsPinDisplay_success() throws Exception {
2007        doAnswer(new AnswerWithArguments() {
2008            public void answer(String ifName, byte[] bssid,
2009                    ISupplicantP2pIface.startWpsPinDisplayCallback cb) {
2010                cb.onValues(mStatusSuccess, "1234");
2011            }
2012        })
2013        .when(mISupplicantP2pIfaceMock).startWpsPinDisplay(
2014                eq(mIfaceName), eq(mPeerMacAddressBytes),
2015                any(ISupplicantP2pIface.startWpsPinDisplayCallback.class));
2016
2017        // Default value when service is not initialized.
2018        assertNull(mDut.startWpsPinDisplay(mIfaceName, mPeerMacAddress));
2019        executeAndValidateInitializationSequence(false, false, false);
2020        assertEquals("1234", mDut.startWpsPinDisplay(mIfaceName, mPeerMacAddress));
2021    }
2022
2023    /**
2024     * StartWpsPinDisplay with invalid arguments.
2025     */
2026    @Test
2027    public void testStartWpsPinDisplay_invalidArguments() throws Exception {
2028        executeAndValidateInitializationSequence(false, false, false);
2029        doAnswer(new AnswerWithArguments() {
2030            public void answer(String ifName, byte[] bssid,
2031                    ISupplicantP2pIface.startWpsPinDisplayCallback cb) {
2032                cb.onValues(mStatusSuccess, "1234");
2033            }
2034        })
2035        .when(mISupplicantP2pIfaceMock).startWpsPinDisplay(
2036                anyString(), any(byte[].class),
2037                any(ISupplicantP2pIface.startWpsPinDisplayCallback.class));
2038
2039        for (String address : mInvalidMacAddresses) {
2040            assertNull(mDut.startWpsPinDisplay(mIfaceName, address));
2041        }
2042
2043        assertNull(mDut.startWpsPinDisplay(null, mPeerMacAddress));
2044    }
2045
2046    /**
2047     * Verify that startWpsPinDisplay returns false, if status is not SUCCESS.
2048     */
2049    @Test
2050    public void testStartWpsPinDisplay_failure() throws Exception {
2051        executeAndValidateInitializationSequence(false, false, false);
2052        doAnswer(new AnswerWithArguments() {
2053            public void answer(String ifName, byte[] bssid,
2054                    ISupplicantP2pIface.startWpsPinDisplayCallback cb) {
2055                cb.onValues(mStatusFailure, "1234");
2056            }
2057        })
2058        .when(mISupplicantP2pIfaceMock).startWpsPinDisplay(
2059                anyString(), any(byte[].class),
2060                any(ISupplicantP2pIface.startWpsPinDisplayCallback.class));
2061
2062        assertNull(mDut.startWpsPinDisplay(mIfaceName, mPeerMacAddress));
2063        // Check that service is still alive.
2064        assertTrue(mDut.isInitializationComplete());
2065    }
2066
2067    /**
2068     * Verify that startWpsPinDisplay disconnects and returns false, if HAL throws exception.
2069     */
2070    @Test
2071    public void testStartWpsPinDisplay_exception() throws Exception {
2072        executeAndValidateInitializationSequence(false, false, false);
2073        doThrow(mRemoteException)
2074                .when(mISupplicantP2pIfaceMock).startWpsPinDisplay(
2075                        anyString(), any(byte[].class),
2076                        any(ISupplicantP2pIface.startWpsPinDisplayCallback.class));
2077        assertNull(mDut.startWpsPinDisplay(mIfaceName, mPeerMacAddress));
2078        // Check service is dead.
2079        assertFalse(mDut.isInitializationComplete());
2080    }
2081
2082
2083    /**
2084     * Sunny day scenario for cancelWps()
2085     */
2086    @Test
2087    public void testCancelWps_success() throws Exception {
2088        when(mISupplicantP2pIfaceMock.cancelWps(eq(mIfaceName)))
2089                .thenReturn(mStatusSuccess);
2090        // Default value when service is not initialized.
2091        assertFalse(mDut.cancelWps(mIfaceName));
2092        executeAndValidateInitializationSequence(false, false, false);
2093        assertTrue(mDut.cancelWps(mIfaceName));
2094    }
2095
2096    /**
2097     * CancelWps with invalid arguments.
2098     */
2099    @Test
2100    public void testCancelWps_invalidArguments() throws Exception {
2101        executeAndValidateInitializationSequence(false, false, false);
2102        when(mISupplicantP2pIfaceMock.cancelWps(anyString()))
2103                .thenReturn(mStatusSuccess);
2104
2105        assertFalse(mDut.cancelWps(null));
2106    }
2107
2108    /**
2109     * Verify that cancelWps returns false, if status is not SUCCESS.
2110     */
2111    @Test
2112    public void testCancelWps_failure() throws Exception {
2113        executeAndValidateInitializationSequence(false, false, false);
2114        when(mISupplicantP2pIfaceMock.cancelWps(anyString()))
2115                .thenReturn(mStatusFailure);
2116        assertFalse(mDut.cancelWps(mIfaceName));
2117        // Check that service is still alive.
2118        assertTrue(mDut.isInitializationComplete());
2119    }
2120
2121    /**
2122     * Verify that cancelWps disconnects and returns false, if HAL throws exception.
2123     */
2124    @Test
2125    public void testCancelWps_exception() throws Exception {
2126        executeAndValidateInitializationSequence(false, false, false);
2127        when(mISupplicantP2pIfaceMock.cancelWps(anyString()))
2128                .thenThrow(mRemoteException);
2129        assertFalse(mDut.cancelWps(mIfaceName));
2130        // Check service is dead.
2131        assertFalse(mDut.isInitializationComplete());
2132    }
2133
2134
2135    /**
2136     * Sunny day scenario for enableWfd()
2137     */
2138    @Test
2139    public void testEnableWfd_success() throws Exception {
2140        when(mISupplicantP2pIfaceMock.enableWfd(eq(true)))
2141                .thenReturn(mStatusSuccess);
2142        // Default value when service is not initialized.
2143        assertFalse(mDut.enableWfd(true));
2144        executeAndValidateInitializationSequence(false, false, false);
2145        assertTrue(mDut.enableWfd(true));
2146    }
2147
2148    /**
2149     * Verify that enableWfd returns false, if status is not SUCCESS.
2150     */
2151    @Test
2152    public void testEnableWfd_failure() throws Exception {
2153        executeAndValidateInitializationSequence(false, false, false);
2154        when(mISupplicantP2pIfaceMock.enableWfd(anyBoolean()))
2155                .thenReturn(mStatusFailure);
2156        assertFalse(mDut.enableWfd(true));
2157        // Check that service is still alive.
2158        assertTrue(mDut.isInitializationComplete());
2159    }
2160
2161    /**
2162     * Verify that enableWfd disconnects and returns false, if HAL throws exception.
2163     */
2164    @Test
2165    public void testEnableWfd_exception() throws Exception {
2166        executeAndValidateInitializationSequence(false, false, false);
2167        when(mISupplicantP2pIfaceMock.enableWfd(anyBoolean()))
2168                .thenThrow(mRemoteException);
2169        assertFalse(mDut.enableWfd(false));
2170        // Check service is dead.
2171        assertFalse(mDut.isInitializationComplete());
2172    }
2173
2174
2175    /**
2176     * Sunny day scenario for setWfdDeviceInfo()
2177     */
2178    @Test
2179    public void testSetWfdDeviceInfo_success() throws Exception {
2180        when(mISupplicantP2pIfaceMock.setWfdDeviceInfo(eq(mValidServiceRequestBytes)))
2181                .thenReturn(mStatusSuccess);
2182        // Default value when service is not initialized.
2183        assertFalse(mDut.setWfdDeviceInfo(mValidServiceRequestString));
2184        executeAndValidateInitializationSequence(false, false, false);
2185        assertTrue(mDut.setWfdDeviceInfo(mValidServiceRequestString));
2186    }
2187
2188    /**
2189     * SetWfdDeviceInfo with invalid arguments.
2190     */
2191    @Test
2192    public void testSetWfdDeviceInfo_invalidArguments() throws Exception {
2193        executeAndValidateInitializationSequence(false, false, false);
2194        when(mISupplicantP2pIfaceMock.setWfdDeviceInfo(any(byte[].class)))
2195                .thenReturn(mStatusSuccess);
2196
2197        assertFalse(mDut.setWfdDeviceInfo(null));
2198        assertFalse(mDut.setWfdDeviceInfo(mInvalidServiceRequestString));
2199    }
2200
2201    /**
2202     * Verify that setWfdDeviceInfo returns false, if status is not SUCCESS.
2203     */
2204    @Test
2205    public void testSetWfdDeviceInfo_failure() throws Exception {
2206        executeAndValidateInitializationSequence(false, false, false);
2207        when(mISupplicantP2pIfaceMock.setWfdDeviceInfo(any(byte[].class)))
2208                .thenReturn(mStatusFailure);
2209        assertFalse(mDut.setWfdDeviceInfo(mValidServiceRequestString));
2210        // Check that service is still alive.
2211        assertTrue(mDut.isInitializationComplete());
2212    }
2213
2214    /**
2215     * Verify that setWfdDeviceInfo disconnects and returns false, if HAL throws exception.
2216     */
2217    @Test
2218    public void testSetWfdDeviceInfo_exception() throws Exception {
2219        executeAndValidateInitializationSequence(false, false, false);
2220        when(mISupplicantP2pIfaceMock.setWfdDeviceInfo(any(byte[].class)))
2221                .thenThrow(mRemoteException);
2222        assertFalse(mDut.setWfdDeviceInfo(mValidServiceRequestString));
2223        // Check service is dead.
2224        assertFalse(mDut.isInitializationComplete());
2225    }
2226
2227    /**
2228     * Verify the loading of group info.
2229     * Specifically, all groups returned by listNetworks are added as a persistent group, so long as
2230     * they are NOT current.
2231     */
2232    @Test
2233    public void testLoadGroups() throws Exception {
2234        executeAndValidateInitializationSequence(false, false, false);
2235
2236        // Class to hold the P2p group info returned from the HIDL interface.
2237        class P2pGroupInfo {
2238            public String ssid;
2239            public byte[] bssid;
2240            public boolean isGo;
2241            public boolean isCurrent;
2242            P2pGroupInfo(String ssid, byte[] bssid, boolean isGo, boolean isCurrent) {
2243                this.ssid = ssid;
2244                this.bssid = bssid;
2245                this.isGo = isGo;
2246                this.isCurrent = isCurrent;
2247            }
2248        }
2249
2250        Map<Integer, P2pGroupInfo> groups = new HashMap<>();
2251        groups.put(0, new P2pGroupInfo(
2252                "test_34",
2253                NativeUtil.macAddressToByteArray("56:34:ab:12:12:34"),
2254                false, false));
2255        groups.put(1, new P2pGroupInfo(
2256                "test_1234",
2257                NativeUtil.macAddressToByteArray("16:ed:ab:12:45:34"),
2258                true, false));
2259        groups.put(2, new P2pGroupInfo(
2260                "test_4545",
2261                NativeUtil.macAddressToByteArray("32:89:23:56:45:34"),
2262                true, false));
2263        groups.put(3, new P2pGroupInfo(
2264                "iShouldntBeHere",
2265                NativeUtil.macAddressToByteArray("aa:bb:cc:56:45:34"),
2266                true, true));
2267
2268        doAnswer(new AnswerWithArguments() {
2269            public void answer(ISupplicantP2pIface.listNetworksCallback cb) {
2270                cb.onValues(mStatusSuccess, new ArrayList<Integer>(groups.keySet()));
2271            }
2272        }).when(mISupplicantP2pIfaceMock)
2273                .listNetworks(any(ISupplicantP2pIface.listNetworksCallback.class));
2274
2275        doAnswer(new AnswerWithArguments() {
2276            public void answer(final int networkId, ISupplicantP2pIface.getNetworkCallback cb) {
2277                try {
2278                    doAnswer(new AnswerWithArguments() {
2279                        public void answer(ISupplicantP2pNetwork.getSsidCallback cb) {
2280                            cb.onValues(mStatusSuccess,
2281                                    NativeUtil.stringToByteArrayList(groups.get(networkId).ssid));
2282                            return;
2283                        }
2284                    }).when(mISupplicantP2pNetworkMock)
2285                            .getSsid(any(ISupplicantP2pNetwork.getSsidCallback.class));
2286                    doAnswer(new AnswerWithArguments() {
2287                        public void answer(ISupplicantP2pNetwork.getBssidCallback cb) {
2288                            cb.onValues(mStatusSuccess, groups.get(networkId).bssid);
2289                            return;
2290                        }
2291                    }).when(mISupplicantP2pNetworkMock)
2292                            .getBssid(any(ISupplicantP2pNetwork.getBssidCallback.class));
2293                    doAnswer(new AnswerWithArguments() {
2294                        public void answer(ISupplicantP2pNetwork.isCurrentCallback cb) {
2295                            cb.onValues(mStatusSuccess, groups.get(networkId).isCurrent);
2296                            return;
2297                        }
2298                    }).when(mISupplicantP2pNetworkMock)
2299                            .isCurrent(any(ISupplicantP2pNetwork.isCurrentCallback.class));
2300                    doAnswer(new AnswerWithArguments() {
2301                        public void answer(ISupplicantP2pNetwork.isGoCallback cb) {
2302                            cb.onValues(mStatusSuccess, groups.get(networkId).isGo);
2303                            return;
2304                        }
2305                    }).when(mISupplicantP2pNetworkMock)
2306                            .isGo(any(ISupplicantP2pNetwork.isGoCallback.class));
2307                } catch (RemoteException e) {
2308                }
2309                cb.onValues(mStatusSuccess, mISupplicantP2pNetworkMock);
2310                return;
2311            }
2312        }).when(mISupplicantP2pIfaceMock)
2313                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2314
2315        WifiP2pGroupList p2pGroups = new WifiP2pGroupList();
2316        assertTrue(mDut.loadGroups(p2pGroups));
2317
2318        assertEquals(3, p2pGroups.getGroupList().size());
2319        for (WifiP2pGroup group : p2pGroups.getGroupList()) {
2320            int networkId = group.getNetworkId();
2321            assertEquals(groups.get(networkId).ssid, group.getNetworkName());
2322            assertEquals(
2323                    NativeUtil.macAddressFromByteArray(groups.get(networkId).bssid),
2324                    group.getOwner().deviceAddress);
2325            assertEquals(groups.get(networkId).isGo, group.isGroupOwner());
2326        }
2327    }
2328
2329    /**
2330     * Sunny day scenario for setClientList()
2331     */
2332    @Test
2333    public void testSetClientList() throws Exception {
2334        int testNetworkId = 5;
2335        final String client1 = mGroupOwnerMacAddress;
2336        final String client2 = mPeerMacAddress;
2337
2338        executeAndValidateInitializationSequence(false, false, false);
2339        doAnswer(new AnswerWithArguments() {
2340            public void answer(final int networkId, ISupplicantP2pIface.getNetworkCallback cb) {
2341                if (networkId == testNetworkId) {
2342                    cb.onValues(mStatusSuccess, mISupplicantP2pNetworkMock);
2343                } else {
2344                    cb.onValues(mStatusFailure, null);
2345                }
2346                return;
2347            }
2348        }).when(mISupplicantP2pIfaceMock)
2349                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2350        when(mISupplicantP2pNetworkMock.setClientList(any(ArrayList.class)))
2351                .thenReturn(mStatusSuccess);
2352
2353        String clientList = client1 + " " + client2;
2354        assertTrue(mDut.setClientList(testNetworkId, clientList));
2355        verify(mISupplicantP2pIfaceMock)
2356                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2357        ArgumentCaptor<ArrayList> capturedClients = ArgumentCaptor.forClass(ArrayList.class);
2358        verify(mISupplicantP2pNetworkMock).setClientList(capturedClients.capture());
2359
2360        // Convert these to long to help with comparisons.
2361        ArrayList<byte[]> clients = capturedClients.getValue();
2362        ArrayList<Long> expectedClients = new ArrayList<Long>() {{
2363                add(NativeUtil.macAddressToLong(mGroupOwnerMacAddressBytes));
2364                add(NativeUtil.macAddressToLong(mPeerMacAddressBytes));
2365            }};
2366        ArrayList<Long> receivedClients = new ArrayList<Long>();
2367        for (byte[] client : clients) {
2368            receivedClients.add(NativeUtil.macAddressToLong(client));
2369        }
2370        assertEquals(expectedClients, receivedClients);
2371    }
2372
2373    /**
2374     * Failure scenario for setClientList() when getNetwork returns null.
2375     */
2376    @Test
2377    public void testSetClientListFailureDueToGetNetwork() throws Exception {
2378        int testNetworkId = 5;
2379        final String client1 = mGroupOwnerMacAddress;
2380        final String client2 = mPeerMacAddress;
2381
2382        executeAndValidateInitializationSequence(false, false, false);
2383        doAnswer(new AnswerWithArguments() {
2384            public void answer(final int networkId, ISupplicantP2pIface.getNetworkCallback cb) {
2385                cb.onValues(mStatusFailure, null);
2386                return;
2387            }
2388        }).when(mISupplicantP2pIfaceMock)
2389                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2390        when(mISupplicantP2pNetworkMock.setClientList(any(ArrayList.class)))
2391                .thenReturn(mStatusSuccess);
2392
2393        String clientList = client1 + " " + client2;
2394        assertFalse(mDut.setClientList(testNetworkId, clientList));
2395        verify(mISupplicantP2pIfaceMock)
2396                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2397        verify(mISupplicantP2pNetworkMock, never()).setClientList(any(ArrayList.class));
2398    }
2399
2400    /**
2401     * Sunny day scenario for getClientList()
2402     */
2403    @Test
2404    public void testGetClientList() throws Exception {
2405        int testNetworkId = 5;
2406        final String client1 = mGroupOwnerMacAddress;
2407        final String client2 = mPeerMacAddress;
2408
2409        executeAndValidateInitializationSequence(false, false, false);
2410        doAnswer(new AnswerWithArguments() {
2411            public void answer(final int networkId, ISupplicantP2pIface.getNetworkCallback cb) {
2412                if (networkId == testNetworkId) {
2413                    cb.onValues(mStatusSuccess, mISupplicantP2pNetworkMock);
2414                } else {
2415                    cb.onValues(mStatusFailure, null);
2416                }
2417                return;
2418            }
2419        }).when(mISupplicantP2pIfaceMock)
2420                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2421        doAnswer(new AnswerWithArguments() {
2422            public void answer(ISupplicantP2pNetwork.getClientListCallback cb) {
2423                ArrayList<byte[]> clients = new ArrayList<byte[]>() {{
2424                        add(mGroupOwnerMacAddressBytes);
2425                        add(mPeerMacAddressBytes);
2426                    }};
2427                cb.onValues(mStatusSuccess, clients);
2428                return;
2429            }
2430        }).when(mISupplicantP2pNetworkMock)
2431                .getClientList(any(ISupplicantP2pNetwork.getClientListCallback.class));
2432
2433        String clientList = client1 + " " + client2;
2434        assertEquals(clientList, mDut.getClientList(testNetworkId));
2435        verify(mISupplicantP2pIfaceMock)
2436                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2437        verify(mISupplicantP2pNetworkMock)
2438                .getClientList(any(ISupplicantP2pNetwork.getClientListCallback.class));
2439    }
2440
2441    /**
2442     * Failure scenario for getClientList() when getNetwork returns null.
2443     */
2444    @Test
2445    public void testGetClientListFailureDueToGetNetwork() throws Exception {
2446        int testNetworkId = 5;
2447        final String client1 = mGroupOwnerMacAddress;
2448        final String client2 = mPeerMacAddress;
2449
2450        executeAndValidateInitializationSequence(false, false, false);
2451        doAnswer(new AnswerWithArguments() {
2452            public void answer(final int networkId, ISupplicantP2pIface.getNetworkCallback cb) {
2453                cb.onValues(mStatusFailure, null);
2454                return;
2455            }
2456        }).when(mISupplicantP2pIfaceMock)
2457                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2458        doAnswer(new AnswerWithArguments() {
2459            public void answer(ISupplicantP2pNetwork.getClientListCallback cb) {
2460                ArrayList<byte[]> clients = new ArrayList<byte[]>() {{
2461                        add(mGroupOwnerMacAddressBytes);
2462                        add(mPeerMacAddressBytes);
2463                    }};
2464                cb.onValues(mStatusSuccess, clients);
2465                return;
2466            }
2467        }).when(mISupplicantP2pNetworkMock)
2468                .getClientList(any(ISupplicantP2pNetwork.getClientListCallback.class));
2469
2470        assertEquals(null, mDut.getClientList(testNetworkId));
2471        verify(mISupplicantP2pIfaceMock)
2472                .getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
2473        verify(mISupplicantP2pNetworkMock, never())
2474                .getClientList(any(ISupplicantP2pNetwork.getClientListCallback.class));
2475    }
2476
2477    /**
2478     * Sunny day scenario for saveConfig()
2479     */
2480    @Test
2481    public void testSaveConfig() throws Exception {
2482        when(mISupplicantP2pIfaceMock.saveConfig()).thenReturn(mStatusSuccess);
2483
2484        // Should fail before initialization.
2485        assertFalse(mDut.saveConfig());
2486        executeAndValidateInitializationSequence(false, false, false);
2487        assertTrue(mDut.saveConfig());
2488        verify(mISupplicantP2pIfaceMock).saveConfig();
2489    }
2490
2491    /**
2492     * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2493     * expected result. Verifies if ISupplicantP2pIface manager is initialized or reset.
2494     * Each of the arguments will cause a different failure mode when set true.
2495     */
2496    private void executeAndValidateInitializationSequence(boolean causeRemoteException,
2497            boolean getZeroInterfaces, boolean getNullInterface) throws Exception {
2498        boolean shouldSucceed = !causeRemoteException && !getZeroInterfaces && !getNullInterface;
2499        // Setup callback mock answers
2500        ArrayList<ISupplicant.IfaceInfo> interfaces;
2501        if (getZeroInterfaces) {
2502            interfaces = new ArrayList<ISupplicant.IfaceInfo>();
2503        } else {
2504            interfaces = mIfaceInfoList;
2505        }
2506
2507        doAnswer(new AnswerWithArguments() {
2508            public void answer(ISupplicant.listInterfacesCallback cb) throws RemoteException {
2509                cb.onValues(mStatusSuccess, interfaces);
2510            }
2511        })
2512        .when(mISupplicantMock).listInterfaces(any(ISupplicant.listInterfacesCallback.class));
2513
2514        if (causeRemoteException) {
2515            doThrow(new RemoteException("Some error!!!"))
2516                    .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class),
2517                    any(ISupplicant.getInterfaceCallback.class));
2518        } else {
2519            doAnswer(new GetGetInterfaceAnswer(getNullInterface))
2520                    .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class),
2521                    any(ISupplicant.getInterfaceCallback.class));
2522        }
2523
2524        mInOrder = inOrder(mServiceManagerMock, mISupplicantMock);
2525        // Initialize SupplicantP2pIfaceHal, should call serviceManager.registerForNotifications
2526        assertTrue(mDut.initialize());
2527        // verify: service manager initialization sequence
2528        mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
2529                anyLong());
2530        mInOrder.verify(mServiceManagerMock).registerForNotifications(
2531                eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2532        // act: cause the onRegistration(...) callback to execute
2533        mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2534
2535        assertEquals(shouldSucceed, mDut.isInitializationComplete());
2536        // verify: listInterfaces is called
2537        mInOrder.verify(mISupplicantMock).listInterfaces(
2538                any(ISupplicant.listInterfacesCallback.class));
2539        if (!getZeroInterfaces) {
2540            mInOrder.verify(mISupplicantMock)
2541                    .getInterface(any(ISupplicant.IfaceInfo.class),
2542                    any(ISupplicant.getInterfaceCallback.class));
2543        }
2544    }
2545
2546
2547    private SupplicantStatus createSupplicantStatus(int code) {
2548        SupplicantStatus status = new SupplicantStatus();
2549        status.code = code;
2550        return status;
2551    }
2552
2553    /**
2554     * Create an IfaceInfo with given type and name
2555     */
2556    private ISupplicant.IfaceInfo createIfaceInfo(int type, String name) {
2557        ISupplicant.IfaceInfo info = new ISupplicant.IfaceInfo();
2558        info.type = type;
2559        info.name = name;
2560        return info;
2561    }
2562
2563    /**
2564     * Create new dummy WifiP2pConfig instance.
2565     */
2566    private WifiP2pConfig createDummyP2pConfig(String peerAddress, int wpsProvMethod, String pin) {
2567        WifiP2pConfig config = new WifiP2pConfig();
2568        config.wps = new WpsInfo();
2569        config.deviceAddress = peerAddress;
2570
2571        config.wps.setup = wpsProvMethod;
2572        config.wps.pin = pin;
2573
2574        return config;
2575    }
2576
2577    /**
2578     * Create new dummy WifiP2pGroup instance.
2579     */
2580    private WifiP2pGroup createDummyP2pGroup() {
2581        WifiP2pGroup group = new WifiP2pGroup();
2582        group.setInterface(mIfaceName);
2583
2584        WifiP2pDevice owner = new WifiP2pDevice();
2585        owner.deviceAddress = mGroupOwnerMacAddress;
2586        group.setOwner(owner);
2587
2588        return group;
2589    }
2590
2591    /**
2592     * Create new dummy WifiP2pServiceInfo instance.
2593     */
2594    private WifiP2pServiceInfo createDummyP2pServiceInfo(String... services) {
2595        class TestP2pServiceInfo extends WifiP2pServiceInfo {
2596            TestP2pServiceInfo(String[] services) {
2597                super(Arrays.asList(services));
2598            }
2599        }
2600        return new TestP2pServiceInfo(services);
2601    }
2602
2603    private class GetGetInterfaceAnswer extends AnswerWithArguments {
2604        boolean mGetNullInterface;
2605
2606        GetGetInterfaceAnswer(boolean getNullInterface) {
2607            mGetNullInterface = getNullInterface;
2608        }
2609
2610        public void answer(ISupplicant.IfaceInfo iface, ISupplicant.getInterfaceCallback cb) {
2611            if (mGetNullInterface) {
2612                cb.onValues(mStatusSuccess, null);
2613            } else {
2614                cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
2615            }
2616        }
2617    }
2618}
2619