WifiAwareManagerTest.java revision afddcc3c9860fecfdb3ed72fafb09d73e8549411
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net.wifi.aware;
18
19import static org.hamcrest.core.IsEqual.equalTo;
20import static org.junit.Assert.assertEquals;
21import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.ArgumentMatchers.anyInt;
23import static org.mockito.ArgumentMatchers.eq;
24import static org.mockito.ArgumentMatchers.isNull;
25import static org.mockito.Mockito.inOrder;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.verifyNoMoreInteractions;
28import static org.mockito.Mockito.when;
29
30import android.content.Context;
31import android.net.wifi.RttManager;
32import android.os.Handler;
33import android.os.IBinder;
34import android.os.Parcel;
35import android.os.test.TestLooper;
36import android.test.suitebuilder.annotation.SmallTest;
37import android.util.Base64;
38
39import libcore.util.HexEncoding;
40
41import org.json.JSONObject;
42import org.junit.Before;
43import org.junit.Rule;
44import org.junit.Test;
45import org.junit.rules.ErrorCollector;
46import org.mockito.ArgumentCaptor;
47import org.mockito.InOrder;
48import org.mockito.Mock;
49import org.mockito.MockitoAnnotations;
50
51import java.util.List;
52
53/**
54 * Unit test harness for WifiAwareManager class.
55 */
56@SmallTest
57public class WifiAwareManagerTest {
58    private WifiAwareManager mDut;
59    private TestLooper mMockLooper;
60    private Handler mMockLooperHandler;
61
62    @Rule
63    public ErrorCollector collector = new ErrorCollector();
64
65    @Mock
66    public Context mockContext;
67
68    @Mock
69    public AttachCallback mockCallback;
70
71    @Mock
72    public DiscoverySessionCallback mockSessionCallback;
73
74    @Mock
75    public IWifiAwareManager mockAwareService;
76
77    @Mock
78    public PublishDiscoverySession mockPublishSession;
79
80    @Mock
81    public SubscribeDiscoverySession mockSubscribeSession;
82
83    @Mock
84    public RttManager.RttListener mockRttListener;
85
86    private static final int AWARE_STATUS_ERROR = -1;
87
88    @Before
89    public void setUp() throws Exception {
90        MockitoAnnotations.initMocks(this);
91
92        mDut = new WifiAwareManager(mockContext, mockAwareService);
93        mMockLooper = new TestLooper();
94        mMockLooperHandler = new Handler(mMockLooper.getLooper());
95    }
96
97    /*
98     * Straight pass-through tests
99     */
100
101    /**
102     * Validate pass-through of isUsageEnabled() API.
103     */
104    @Test
105    public void testIsUsageEnable() throws Exception {
106        mDut.isAvailable();
107
108        verify(mockAwareService).isUsageEnabled();
109    }
110
111    /**
112     * Validate pass-through of getCharacteristics() API.
113     */
114    @Test
115    public void testGetCharacteristics() throws Exception {
116        mDut.getCharacteristics();
117
118        verify(mockAwareService).getCharacteristics();
119    }
120
121    /*
122     * WifiAwareEventCallbackProxy Tests
123     */
124
125    /**
126     * Validate the successful connect flow: (1) connect + success (2) publish, (3) disconnect
127     * (4) try publishing on old session (5) connect again
128     */
129    @Test
130    public void testConnectFlow() throws Exception {
131        final int clientId = 4565;
132
133        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
134        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
135                .forClass(IWifiAwareEventCallback.class);
136        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
137                WifiAwareSession.class);
138        ArgumentCaptor<IBinder> binder = ArgumentCaptor.forClass(IBinder.class);
139
140        // (1) connect + success
141        mDut.attach(mockCallback, mMockLooperHandler);
142        inOrder.verify(mockAwareService).connect(binder.capture(), any(),
143                clientProxyCallback.capture(), isNull(), eq(false));
144        clientProxyCallback.getValue().onConnectSuccess(clientId);
145        mMockLooper.dispatchAll();
146        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
147        WifiAwareSession session = sessionCaptor.getValue();
148
149        // (2) publish - should succeed
150        PublishConfig publishConfig = new PublishConfig.Builder().build();
151        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
152        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig), any());
153
154        // (3) disconnect
155        session.destroy();
156        inOrder.verify(mockAwareService).disconnect(eq(clientId), eq(binder.getValue()));
157
158        // (4) try publishing again - fails silently
159        session.publish(new PublishConfig.Builder().build(), mockSessionCallback,
160                mMockLooperHandler);
161
162        // (5) connect
163        mDut.attach(mockCallback, mMockLooperHandler);
164        inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), isNull(),
165                eq(false));
166
167        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
168    }
169
170    /**
171     * Validate the failed connect flow: (1) connect + failure, (2) connect + success (3) subscribe
172     */
173    @Test
174    public void testConnectFailure() throws Exception {
175        final int clientId = 4565;
176        final int reason = AWARE_STATUS_ERROR;
177
178        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
179        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
180                WifiAwareSession.class);
181        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
182                .forClass(IWifiAwareEventCallback.class);
183
184        // (1) connect + failure
185        mDut.attach(mockCallback, mMockLooperHandler);
186        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
187                isNull(), eq(false));
188        clientProxyCallback.getValue().onConnectFail(reason);
189        mMockLooper.dispatchAll();
190        inOrder.verify(mockCallback).onAttachFailed();
191
192        // (2) connect + success
193        mDut.attach(mockCallback, mMockLooperHandler);
194        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
195                isNull(), eq(false));
196        clientProxyCallback.getValue().onConnectSuccess(clientId);
197        mMockLooper.dispatchAll();
198        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
199        WifiAwareSession session = sessionCaptor.getValue();
200
201        // (4) subscribe: should succeed
202        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
203        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
204        inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig), any());
205
206        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
207    }
208
209    /**
210     * Validate that can call connect to create multiple sessions: (1) connect
211     * + success, (2) try connect again
212     */
213    @Test
214    public void testInvalidConnectSequence() throws Exception {
215        final int clientId = 4565;
216
217        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService);
218        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
219                .forClass(IWifiAwareEventCallback.class);
220
221        // (1) connect + success
222        mDut.attach(mockCallback, mMockLooperHandler);
223        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
224                isNull(), eq(false));
225        clientProxyCallback.getValue().onConnectSuccess(clientId);
226        mMockLooper.dispatchAll();
227        inOrder.verify(mockCallback).onAttached(any());
228
229        // (2) connect + success
230        mDut.attach(mockCallback, mMockLooperHandler);
231        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
232                isNull(), eq(false));
233        clientProxyCallback.getValue().onConnectSuccess(clientId + 1);
234        mMockLooper.dispatchAll();
235        inOrder.verify(mockCallback).onAttached(any());
236
237        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
238    }
239
240    /*
241     * WifiAwareDiscoverySessionCallbackProxy Tests
242     */
243
244    /**
245     * Validate the publish flow: (0) connect + success, (1) publish, (2)
246     * success creates session, (3) pass through everything, (4) update publish
247     * through session, (5) terminate locally, (6) try another command -
248     * ignored.
249     */
250    @Test
251    public void testPublishFlow() throws Exception {
252        final int clientId = 4565;
253        final int sessionId = 123;
254        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
255        final PublishConfig publishConfig = new PublishConfig.Builder().build();
256        final PeerHandle peerHandle = new PeerHandle(873);
257        final String string1 = "hey from here...";
258        final byte[] matchFilter = { 1, 12, 2, 31, 32 };
259        final int messageId = 2123;
260        final int reason = AWARE_STATUS_ERROR;
261
262        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
263                mockPublishSession);
264        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
265                WifiAwareSession.class);
266        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
267                .forClass(IWifiAwareEventCallback.class);
268        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
269                .forClass(IWifiAwareDiscoverySessionCallback.class);
270        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
271                .forClass(PublishDiscoverySession.class);
272        ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
273        ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
274                (Class) List.class);
275
276        // (0) connect + success
277        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
278        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
279                eq(configRequest), eq(false));
280        clientProxyCallback.getValue().onConnectSuccess(clientId);
281        mMockLooper.dispatchAll();
282        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
283        WifiAwareSession session = sessionCaptor.getValue();
284
285        // (1) publish
286        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
287        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
288                sessionProxyCallback.capture());
289
290        // (2) publish session created
291        sessionProxyCallback.getValue().onSessionStarted(sessionId);
292        mMockLooper.dispatchAll();
293        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
294
295        // (3) ...
296        publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
297        sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
298        sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
299        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
300        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
301        mMockLooper.dispatchAll();
302
303        inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
304                eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
305        inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
306                eq(string1.getBytes()),
307                matchFilterCaptor.capture());
308
309        // note: need to capture/compare elements since the Mockito eq() is a shallow comparator
310        List<byte[]> parsedMatchFilter = new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList();
311        collector.checkThat("match-filter-size", parsedMatchFilter.size(),
312                equalTo(matchFilterCaptor.getValue().size()));
313        collector.checkThat("match-filter-entry0", parsedMatchFilter.get(0),
314                equalTo(matchFilterCaptor.getValue().get(0)));
315        collector.checkThat("match-filter-entry1", parsedMatchFilter.get(1),
316                equalTo(matchFilterCaptor.getValue().get(1)));
317
318        assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
319        inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
320                eq(string1.getBytes()));
321        assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
322        inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
323        inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
324
325        // (4) update publish
326        publishSession.getValue().updatePublish(publishConfig);
327        sessionProxyCallback.getValue().onSessionConfigFail(reason);
328        mMockLooper.dispatchAll();
329        inOrder.verify(mockAwareService).updatePublish(eq(clientId), eq(sessionId),
330                eq(publishConfig));
331        inOrder.verify(mockSessionCallback).onSessionConfigFailed();
332
333        // (5) terminate
334        publishSession.getValue().destroy();
335        mMockLooper.dispatchAll();
336        inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
337
338        // (6) try an update (nothing)
339        publishSession.getValue().updatePublish(publishConfig);
340        mMockLooper.dispatchAll();
341
342        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
343                mockPublishSession);
344    }
345
346    /**
347     * Validate race condition of session terminate and session action: (1)
348     * connect, (2) publish success + terminate, (3) update.
349     */
350    @Test
351    public void testPublishRemoteTerminate() throws Exception {
352        final int clientId = 4565;
353        final int sessionId = 123;
354        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
355        final PublishConfig publishConfig = new PublishConfig.Builder().build();
356
357        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
358                mockPublishSession);
359        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
360                WifiAwareSession.class);
361        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
362                .forClass(IWifiAwareEventCallback.class);
363        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
364                .forClass(IWifiAwareDiscoverySessionCallback.class);
365        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
366                .forClass(PublishDiscoverySession.class);
367
368        // (1) connect successfully
369        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
370        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
371                eq(configRequest), eq(false));
372        clientProxyCallback.getValue().onConnectSuccess(clientId);
373        mMockLooper.dispatchAll();
374        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
375        WifiAwareSession session = sessionCaptor.getValue();
376
377        // (2) publish: successfully - then terminated
378        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
379        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
380                sessionProxyCallback.capture());
381        sessionProxyCallback.getValue().onSessionStarted(sessionId);
382        sessionProxyCallback.getValue().onSessionTerminated(0);
383        mMockLooper.dispatchAll();
384        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
385        inOrder.verify(mockSessionCallback).onSessionTerminated();
386
387        // (3) failure when trying to update: NOP
388        publishSession.getValue().updatePublish(publishConfig);
389
390        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
391                mockPublishSession);
392    }
393
394    /**
395     * Validate the subscribe flow: (0) connect + success, (1) subscribe, (2)
396     * success creates session, (3) pass through everything, (4) update
397     * subscribe through session, (5) terminate locally, (6) try another command
398     * - ignored.
399     */
400    @Test
401    public void testSubscribeFlow() throws Exception {
402        final int clientId = 4565;
403        final int sessionId = 123;
404        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
405        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
406        final PeerHandle peerHandle = new PeerHandle(873);
407        final String string1 = "hey from here...";
408        final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
409        final int messageId = 2123;
410        final int reason = AWARE_STATUS_ERROR;
411
412        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
413                mockSubscribeSession);
414        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
415                WifiAwareSession.class);
416        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
417                .forClass(IWifiAwareEventCallback.class);
418        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
419                .forClass(IWifiAwareDiscoverySessionCallback.class);
420        ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
421                .forClass(SubscribeDiscoverySession.class);
422        ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
423
424        // (0) connect + success
425        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
426        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
427                eq(configRequest), eq(false));
428        clientProxyCallback.getValue().onConnectSuccess(clientId);
429        mMockLooper.dispatchAll();
430        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
431        WifiAwareSession session = sessionCaptor.getValue();
432
433        // (1) subscribe
434        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
435        inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig),
436                sessionProxyCallback.capture());
437
438        // (2) subscribe session created
439        sessionProxyCallback.getValue().onSessionStarted(sessionId);
440        mMockLooper.dispatchAll();
441        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
442
443        // (3) ...
444        subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
445        sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
446        sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
447        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
448        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
449        mMockLooper.dispatchAll();
450
451        inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
452                eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
453        inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
454                eq(string1.getBytes()), (List<byte[]>) isNull());
455        assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
456        inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
457                eq(string1.getBytes()));
458        assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
459        inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
460        inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
461
462        // (4) update subscribe
463        subscribeSession.getValue().updateSubscribe(subscribeConfig);
464        sessionProxyCallback.getValue().onSessionConfigFail(reason);
465        mMockLooper.dispatchAll();
466        inOrder.verify(mockAwareService).updateSubscribe(eq(clientId), eq(sessionId),
467                eq(subscribeConfig));
468        inOrder.verify(mockSessionCallback).onSessionConfigFailed();
469
470        // (5) terminate
471        subscribeSession.getValue().destroy();
472        mMockLooper.dispatchAll();
473        inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
474
475        // (6) try an update (nothing)
476        subscribeSession.getValue().updateSubscribe(subscribeConfig);
477        mMockLooper.dispatchAll();
478
479        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
480                mockSubscribeSession);
481    }
482
483    /**
484     * Validate race condition of session terminate and session action: (1)
485     * connect, (2) subscribe success + terminate, (3) update.
486     */
487    @Test
488    public void testSubscribeRemoteTerminate() throws Exception {
489        final int clientId = 4565;
490        final int sessionId = 123;
491        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
492        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
493
494        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
495                mockSubscribeSession);
496        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
497                WifiAwareSession.class);
498        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
499                .forClass(IWifiAwareEventCallback.class);
500        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
501                .forClass(IWifiAwareDiscoverySessionCallback.class);
502        ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
503                .forClass(SubscribeDiscoverySession.class);
504
505        // (1) connect successfully
506        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
507        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
508                eq(configRequest), eq(false));
509        clientProxyCallback.getValue().onConnectSuccess(clientId);
510        mMockLooper.dispatchAll();
511        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
512        WifiAwareSession session = sessionCaptor.getValue();
513
514        // (2) subscribe: successfully - then terminated
515        session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
516        inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig),
517                sessionProxyCallback.capture());
518        sessionProxyCallback.getValue().onSessionStarted(sessionId);
519        sessionProxyCallback.getValue().onSessionTerminated(0);
520        mMockLooper.dispatchAll();
521        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
522        inOrder.verify(mockSessionCallback).onSessionTerminated();
523
524        // (3) failure when trying to update: NOP
525        subscribeSession.getValue().updateSubscribe(subscribeConfig);
526
527        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
528                mockSubscribeSession);
529    }
530
531    /*
532     * ConfigRequest Tests
533     */
534
535    @Test
536    public void testConfigRequestBuilderDefaults() {
537        ConfigRequest configRequest = new ConfigRequest.Builder().build();
538
539        collector.checkThat("mClusterHigh", ConfigRequest.CLUSTER_ID_MAX,
540                equalTo(configRequest.mClusterHigh));
541        collector.checkThat("mClusterLow", ConfigRequest.CLUSTER_ID_MIN,
542                equalTo(configRequest.mClusterLow));
543        collector.checkThat("mMasterPreference", 0,
544                equalTo(configRequest.mMasterPreference));
545        collector.checkThat("mSupport5gBand", false, equalTo(configRequest.mSupport5gBand));
546        collector.checkThat("mDiscoveryWindowInterval.length", 2,
547                equalTo(configRequest.mDiscoveryWindowInterval.length));
548        collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
549                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
550        collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
551                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
552    }
553
554    @Test
555    public void testConfigRequestBuilder() {
556        final int clusterHigh = 100;
557        final int clusterLow = 5;
558        final int masterPreference = 55;
559        final boolean supportBand5g = true;
560        final int dwWindow5GHz = 3;
561
562        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
563                .setClusterLow(clusterLow).setMasterPreference(masterPreference)
564                .setSupport5gBand(supportBand5g)
565                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
566                .build();
567
568        collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
569        collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow));
570        collector.checkThat("mMasterPreference", masterPreference,
571                equalTo(configRequest.mMasterPreference));
572        collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand));
573        collector.checkThat("mDiscoveryWindowInterval.length", 2,
574                equalTo(configRequest.mDiscoveryWindowInterval.length));
575        collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
576                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
577        collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz,
578                equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
579    }
580
581    @Test(expected = IllegalArgumentException.class)
582    public void testConfigRequestBuilderMasterPrefNegative() {
583        ConfigRequest.Builder builder = new ConfigRequest.Builder();
584        builder.setMasterPreference(-1);
585    }
586
587    @Test(expected = IllegalArgumentException.class)
588    public void testConfigRequestBuilderMasterPrefReserved1() {
589        new ConfigRequest.Builder().setMasterPreference(1);
590    }
591
592    @Test(expected = IllegalArgumentException.class)
593    public void testConfigRequestBuilderMasterPrefReserved255() {
594        new ConfigRequest.Builder().setMasterPreference(255);
595    }
596
597    @Test(expected = IllegalArgumentException.class)
598    public void testConfigRequestBuilderMasterPrefTooLarge() {
599        new ConfigRequest.Builder().setMasterPreference(256);
600    }
601
602    @Test(expected = IllegalArgumentException.class)
603    public void testConfigRequestBuilderClusterLowNegative() {
604        new ConfigRequest.Builder().setClusterLow(-1);
605    }
606
607    @Test(expected = IllegalArgumentException.class)
608    public void testConfigRequestBuilderClusterHighNegative() {
609        new ConfigRequest.Builder().setClusterHigh(-1);
610    }
611
612    @Test(expected = IllegalArgumentException.class)
613    public void testConfigRequestBuilderClusterLowAboveMax() {
614        new ConfigRequest.Builder().setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1);
615    }
616
617    @Test(expected = IllegalArgumentException.class)
618    public void testConfigRequestBuilderClusterHighAboveMax() {
619        new ConfigRequest.Builder().setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1);
620    }
621
622    @Test(expected = IllegalArgumentException.class)
623    public void testConfigRequestBuilderClusterLowLargerThanHigh() {
624        new ConfigRequest.Builder().setClusterLow(100).setClusterHigh(5).build();
625    }
626
627    @Test(expected = IllegalArgumentException.class)
628    public void testConfigRequestBuilderDwIntervalInvalidBand() {
629        new ConfigRequest.Builder().setDiscoveryWindowInterval(5, 1).build();
630    }
631
632    @Test(expected = IllegalArgumentException.class)
633    public void testConfigRequestBuilderDwIntervalInvalidValueZero() {
634        new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ,
635                0).build();
636    }
637
638    @Test(expected = IllegalArgumentException.class)
639    public void testConfigRequestBuilderDwIntervalInvalidValueLarge() {
640        new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ,
641                6).build();
642    }
643
644    @Test(expected = IllegalArgumentException.class)
645    public void testConfigRequestBuilderDwIntervalInvalidValueLargeValidate() {
646        ConfigRequest cr = new ConfigRequest.Builder().build();
647        cr.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ] = 6;
648        cr.validate();
649    }
650
651    @Test
652    public void testConfigRequestParcel() {
653        final int clusterHigh = 189;
654        final int clusterLow = 25;
655        final int masterPreference = 177;
656        final boolean supportBand5g = true;
657        final int dwWindow24GHz = 1;
658        final int dwWindow5GHz = 5;
659
660        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
661                .setClusterLow(clusterLow).setMasterPreference(masterPreference)
662                .setSupport5gBand(supportBand5g)
663                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz)
664                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
665                .build();
666
667        Parcel parcelW = Parcel.obtain();
668        configRequest.writeToParcel(parcelW, 0);
669        byte[] bytes = parcelW.marshall();
670        parcelW.recycle();
671
672        Parcel parcelR = Parcel.obtain();
673        parcelR.unmarshall(bytes, 0, bytes.length);
674        parcelR.setDataPosition(0);
675        ConfigRequest rereadConfigRequest = ConfigRequest.CREATOR.createFromParcel(parcelR);
676
677        assertEquals(configRequest, rereadConfigRequest);
678    }
679
680    /*
681     * SubscribeConfig Tests
682     */
683
684    @Test
685    public void testSubscribeConfigBuilderDefaults() {
686        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
687
688        collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null));
689        collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
690                equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
691        collector.checkThat("mSubscribeCount", subscribeConfig.mSubscribeCount, equalTo(0));
692        collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
693        collector.checkThat("mMatchStyle", subscribeConfig.mMatchStyle,
694                equalTo(SubscribeConfig.MATCH_STYLE_ALL));
695        collector.checkThat("mEnableTerminateNotification",
696                subscribeConfig.mEnableTerminateNotification, equalTo(true));
697    }
698
699    @Test
700    public void testSubscribeConfigBuilder() {
701        final String serviceName = "some_service_or_other";
702        final String serviceSpecificInfo = "long arbitrary string with some info";
703        final byte[] matchFilter = { 1, 16, 1, 22 };
704        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
705        final int subscribeCount = 10;
706        final int subscribeTtl = 15;
707        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
708        final boolean enableTerminateNotification = false;
709
710        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
711                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
712                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
713                .setSubscribeType(subscribeType)
714                .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
715                .setTerminateNotificationEnabled(enableTerminateNotification).build();
716
717        collector.checkThat("mServiceName", serviceName.getBytes(),
718                equalTo(subscribeConfig.mServiceName));
719        collector.checkThat("mServiceSpecificInfo",
720                serviceSpecificInfo.getBytes(), equalTo(subscribeConfig.mServiceSpecificInfo));
721        collector.checkThat("mMatchFilter", matchFilter, equalTo(subscribeConfig.mMatchFilter));
722        collector.checkThat("mSubscribeType", subscribeType,
723                equalTo(subscribeConfig.mSubscribeType));
724        collector.checkThat("mSubscribeCount", subscribeCount,
725                equalTo(subscribeConfig.mSubscribeCount));
726        collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
727        collector.checkThat("mMatchStyle", matchStyle, equalTo(subscribeConfig.mMatchStyle));
728        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
729                equalTo(subscribeConfig.mEnableTerminateNotification));
730    }
731
732    @Test
733    public void testSubscribeConfigParcel() {
734        final String serviceName = "some_service_or_other";
735        final String serviceSpecificInfo = "long arbitrary string with some info";
736        final byte[] matchFilter = { 1, 16, 1, 22 };
737        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
738        final int subscribeCount = 10;
739        final int subscribeTtl = 15;
740        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
741        final boolean enableTerminateNotification = true;
742
743        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
744                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
745                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
746                .setSubscribeType(subscribeType)
747                .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
748                .setTerminateNotificationEnabled(enableTerminateNotification).build();
749
750        Parcel parcelW = Parcel.obtain();
751        subscribeConfig.writeToParcel(parcelW, 0);
752        byte[] bytes = parcelW.marshall();
753        parcelW.recycle();
754
755        Parcel parcelR = Parcel.obtain();
756        parcelR.unmarshall(bytes, 0, bytes.length);
757        parcelR.setDataPosition(0);
758        SubscribeConfig rereadSubscribeConfig = SubscribeConfig.CREATOR.createFromParcel(parcelR);
759
760        assertEquals(subscribeConfig, rereadSubscribeConfig);
761    }
762
763    @Test(expected = IllegalArgumentException.class)
764    public void testSubscribeConfigBuilderBadSubscribeType() {
765        new SubscribeConfig.Builder().setSubscribeType(10);
766    }
767
768    @Test(expected = IllegalArgumentException.class)
769    public void testSubscribeConfigBuilderNegativeCount() {
770        new SubscribeConfig.Builder().setSubscribeCount(-1);
771    }
772
773    @Test(expected = IllegalArgumentException.class)
774    public void testSubscribeConfigBuilderNegativeTtl() {
775        new SubscribeConfig.Builder().setTtlSec(-100);
776    }
777
778    /**
779     * Validate that a bad match style configuration throws an exception.
780     */
781    @Test(expected = IllegalArgumentException.class)
782    public void testSubscribeConfigBuilderBadMatchStyle() {
783        new SubscribeConfig.Builder().setMatchStyle(10);
784    }
785
786    /*
787     * PublishConfig Tests
788     */
789
790    @Test
791    public void testPublishConfigBuilderDefaults() {
792        PublishConfig publishConfig = new PublishConfig.Builder().build();
793
794        collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null));
795        collector.checkThat("mPublishType", publishConfig.mPublishType,
796                equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED));
797        collector.checkThat("mPublishCount", publishConfig.mPublishCount, equalTo(0));
798        collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0));
799        collector.checkThat("mEnableTerminateNotification",
800                publishConfig.mEnableTerminateNotification, equalTo(true));
801    }
802
803    @Test
804    public void testPublishConfigBuilder() {
805        final String serviceName = "some_service_or_other";
806        final String serviceSpecificInfo = "long arbitrary string with some info";
807        final byte[] matchFilter = { 1, 16, 1, 22 };
808        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
809        final int publishCount = 10;
810        final int publishTtl = 15;
811        final boolean enableTerminateNotification = false;
812
813        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
814                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
815                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
816                .setPublishType(publishType)
817                .setPublishCount(publishCount).setTtlSec(publishTtl)
818                .setTerminateNotificationEnabled(enableTerminateNotification).build();
819
820        collector.checkThat("mServiceName", serviceName.getBytes(),
821                equalTo(publishConfig.mServiceName));
822        collector.checkThat("mServiceSpecificInfo",
823                serviceSpecificInfo.getBytes(), equalTo(publishConfig.mServiceSpecificInfo));
824        collector.checkThat("mMatchFilter", matchFilter, equalTo(publishConfig.mMatchFilter));
825        collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType));
826        collector.checkThat("mPublishCount", publishCount, equalTo(publishConfig.mPublishCount));
827        collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec));
828        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
829                equalTo(publishConfig.mEnableTerminateNotification));
830    }
831
832    @Test
833    public void testPublishConfigParcel() {
834        final String serviceName = "some_service_or_other";
835        final String serviceSpecificInfo = "long arbitrary string with some info";
836        final byte[] matchFilter = { 1, 16, 1, 22 };
837        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
838        final int publishCount = 10;
839        final int publishTtl = 15;
840        final boolean enableTerminateNotification = false;
841
842        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
843                .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
844                        new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
845                .setPublishType(publishType)
846                .setPublishCount(publishCount).setTtlSec(publishTtl)
847                .setTerminateNotificationEnabled(enableTerminateNotification).build();
848
849        Parcel parcelW = Parcel.obtain();
850        publishConfig.writeToParcel(parcelW, 0);
851        byte[] bytes = parcelW.marshall();
852        parcelW.recycle();
853
854        Parcel parcelR = Parcel.obtain();
855        parcelR.unmarshall(bytes, 0, bytes.length);
856        parcelR.setDataPosition(0);
857        PublishConfig rereadPublishConfig = PublishConfig.CREATOR.createFromParcel(parcelR);
858
859        assertEquals(publishConfig, rereadPublishConfig);
860    }
861
862    @Test(expected = IllegalArgumentException.class)
863    public void testPublishConfigBuilderBadPublishType() {
864        new PublishConfig.Builder().setPublishType(5);
865    }
866
867    @Test(expected = IllegalArgumentException.class)
868    public void testPublishConfigBuilderNegativeCount() {
869        new PublishConfig.Builder().setPublishCount(-4);
870    }
871
872    @Test(expected = IllegalArgumentException.class)
873    public void testPublishConfigBuilderNegativeTtl() {
874        new PublishConfig.Builder().setTtlSec(-10);
875    }
876
877    /*
878     * Ranging tests
879     */
880
881    /**
882     * Validate ranging + success flow: (1) connect, (2) create a (publish) session, (3) start
883     * ranging, (4) ranging success callback, (5) ranging aborted callback ignored (since
884     * listener removed).
885     */
886    @Test
887    public void testRangingCallbacks() throws Exception {
888        final int clientId = 4565;
889        final int sessionId = 123;
890        final int rangingId = 3482;
891        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
892        final PublishConfig publishConfig = new PublishConfig.Builder().build();
893        final RttManager.RttParams rttParams = new RttManager.RttParams();
894        rttParams.deviceType = RttManager.RTT_PEER_NAN;
895        rttParams.bssid = Integer.toString(1234);
896        final RttManager.RttResult rttResults = new RttManager.RttResult();
897        rttResults.distance = 10;
898
899        when(mockAwareService.startRanging(anyInt(), anyInt(), any())).thenReturn(rangingId);
900
901        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
902                mockPublishSession, mockRttListener);
903        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
904                WifiAwareSession.class);
905        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
906                .forClass(IWifiAwareEventCallback.class);
907        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
908                .forClass(IWifiAwareDiscoverySessionCallback.class);
909        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
910                .forClass(PublishDiscoverySession.class);
911        ArgumentCaptor<RttManager.ParcelableRttParams> rttParamCaptor = ArgumentCaptor
912                .forClass(RttManager.ParcelableRttParams.class);
913        ArgumentCaptor<RttManager.RttResult[]> rttResultsCaptor = ArgumentCaptor
914                .forClass(RttManager.RttResult[].class);
915
916        // (1) connect successfully
917        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
918        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
919                eq(configRequest), eq(false));
920        clientProxyCallback.getValue().onConnectSuccess(clientId);
921        mMockLooper.dispatchAll();
922        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
923        WifiAwareSession session = sessionCaptor.getValue();
924
925        // (2) publish successfully
926        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
927        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
928                sessionProxyCallback.capture());
929        sessionProxyCallback.getValue().onSessionStarted(sessionId);
930        mMockLooper.dispatchAll();
931        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
932
933        // (3) start ranging
934        publishSession.getValue().startRanging(new RttManager.RttParams[]{rttParams},
935                mockRttListener);
936        inOrder.verify(mockAwareService).startRanging(eq(clientId), eq(sessionId),
937                rttParamCaptor.capture());
938        collector.checkThat("RttParams.deviceType", rttParams.deviceType,
939                equalTo(rttParamCaptor.getValue().mParams[0].deviceType));
940        collector.checkThat("RttParams.bssid", rttParams.bssid,
941                equalTo(rttParamCaptor.getValue().mParams[0].bssid));
942
943        // (4) ranging success callback
944        clientProxyCallback.getValue().onRangingSuccess(rangingId,
945                new RttManager.ParcelableRttResults(new RttManager.RttResult[] { rttResults }));
946        mMockLooper.dispatchAll();
947        inOrder.verify(mockRttListener).onSuccess(rttResultsCaptor.capture());
948        collector.checkThat("RttResult.distance", rttResults.distance,
949                equalTo(rttResultsCaptor.getValue()[0].distance));
950
951        // (5) ranging aborted callback (should be ignored since listener cleared on first callback)
952        clientProxyCallback.getValue().onRangingAborted(rangingId);
953        mMockLooper.dispatchAll();
954
955        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
956                mockPublishSession, mockRttListener);
957    }
958
959    /*
960     * Data-path tests
961     */
962
963    /**
964     * Validate that correct network specifier is generated for client-based data-path.
965     */
966    @Test
967    public void testNetworkSpecifierWithClient() throws Exception {
968        final int clientId = 4565;
969        final int sessionId = 123;
970        final PeerHandle peerHandle = new PeerHandle(123412);
971        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
972        final byte[] pmk = "Some arbitrary byte array".getBytes();
973        final String passphrase = "A really bad password";
974        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
975        final PublishConfig publishConfig = new PublishConfig.Builder().build();
976
977        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
978
979        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
980                WifiAwareSession.class);
981        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
982                .forClass(IWifiAwareEventCallback.class);
983        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
984                .forClass(IWifiAwareDiscoverySessionCallback.class);
985        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
986                .forClass(PublishDiscoverySession.class);
987
988        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
989                mockPublishSession, mockRttListener);
990
991        // (1) connect successfully
992        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
993        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
994                eq(configRequest), eq(false));
995        clientProxyCallback.getValue().onConnectSuccess(clientId);
996        mMockLooper.dispatchAll();
997        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
998        WifiAwareSession session = sessionCaptor.getValue();
999
1000        // (2) publish successfully
1001        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
1002        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
1003                sessionProxyCallback.capture());
1004        sessionProxyCallback.getValue().onSessionStarted(sessionId);
1005        mMockLooper.dispatchAll();
1006        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
1007
1008        // (3) request an open (unencrypted) network specifier from the session
1009        String networkSpecifier = publishSession.getValue().createNetworkSpecifierOpen(peerHandle);
1010
1011        // validate format
1012        JSONObject jsonObject = new JSONObject(networkSpecifier);
1013        collector.checkThat("role", role,
1014                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1015        collector.checkThat("client_id", clientId,
1016                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1017        collector.checkThat("session_id", sessionId,
1018                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
1019        collector.checkThat("peer_id", peerHandle.peerId,
1020                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
1021
1022        // (4) request an encrypted (PMK) network specifier from the session
1023        networkSpecifier = publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
1024
1025        // validate format
1026        jsonObject = new JSONObject(networkSpecifier);
1027        collector.checkThat("role", role,
1028                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1029        collector.checkThat("client_id", clientId,
1030                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1031        collector.checkThat("session_id", sessionId,
1032                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
1033        collector.checkThat("peer_id", peerHandle.peerId,
1034                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
1035        collector.checkThat("pmk", pmkB64 ,
1036                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
1037
1038        // (5) request an encrypted (Passphrase) network specifier from the session
1039        networkSpecifier = publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle,
1040                passphrase);
1041
1042        // validate format
1043        jsonObject = new JSONObject(networkSpecifier);
1044        collector.checkThat("role", role,
1045                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1046        collector.checkThat("client_id", clientId,
1047                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1048        collector.checkThat("session_id", sessionId,
1049                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
1050        collector.checkThat("peer_id", peerHandle.peerId,
1051                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
1052        collector.checkThat("passphrase", passphrase,
1053                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));
1054
1055        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
1056                mockPublishSession, mockRttListener);
1057    }
1058
1059    /**
1060     * Validate that correct network specifier is generated for a direct data-path (i.e.
1061     * specifying MAC address as opposed to a client-based oqaque specification).
1062     */
1063    @Test
1064    public void testNetworkSpecifierDirect() throws Exception {
1065        final int clientId = 134;
1066        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1067        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
1068        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
1069        final byte[] pmk = "Some arbitrary pmk data".getBytes();
1070        final String passphrase = "A really bad password";
1071
1072        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
1073
1074        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
1075                WifiAwareSession.class);
1076        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
1077                .forClass(IWifiAwareEventCallback.class);
1078
1079        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
1080                mockPublishSession, mockRttListener);
1081
1082        // (1) connect successfully
1083        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
1084        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
1085                eq(configRequest), eq(false));
1086        clientProxyCallback.getValue().onConnectSuccess(clientId);
1087        mMockLooper.dispatchAll();
1088        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
1089        WifiAwareSession session = sessionCaptor.getValue();
1090
1091        // (2) request an open (unencrypted) direct network specifier
1092        String networkSpecifier = session.createNetworkSpecifierOpen(role, someMac);
1093
1094        // validate format
1095        JSONObject jsonObject = new JSONObject(networkSpecifier);
1096        collector.checkThat("role", role,
1097                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1098        collector.checkThat("client_id", clientId,
1099                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1100        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
1101                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
1102                false)));
1103
1104        // (3) request an encrypted (PMK) direct network specifier
1105        networkSpecifier = session.createNetworkSpecifierPmk(role, someMac, pmk);
1106
1107        // validate format
1108        jsonObject = new JSONObject(networkSpecifier);
1109        collector.checkThat("role", role,
1110                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1111        collector.checkThat("client_id", clientId,
1112                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1113        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
1114                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
1115                false)));
1116        collector.checkThat("pmk", pmkB64,
1117                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
1118
1119        // (4) request an encrypted (Passphrase) direct network specifier
1120        networkSpecifier = session.createNetworkSpecifierPassphrase(role, someMac, passphrase);
1121
1122        // validate format
1123        jsonObject = new JSONObject(networkSpecifier);
1124        collector.checkThat("role", role,
1125                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
1126        collector.checkThat("client_id", clientId,
1127                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
1128        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
1129                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
1130                false)));
1131        collector.checkThat("passphrase", passphrase,
1132                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));
1133
1134        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
1135                mockPublishSession, mockRttListener);
1136    }
1137}
1138