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 
17 package com.android.server.wifi.aware;
18 
19 import static android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
20 
21 import static org.hamcrest.core.IsEqual.equalTo;
22 import static org.junit.Assert.assertArrayEquals;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotEquals;
25 import static org.junit.Assert.assertTrue;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyBoolean;
28 import static org.mockito.ArgumentMatchers.anyInt;
29 import static org.mockito.ArgumentMatchers.anyLong;
30 import static org.mockito.ArgumentMatchers.anyShort;
31 import static org.mockito.ArgumentMatchers.anyString;
32 import static org.mockito.ArgumentMatchers.eq;
33 import static org.mockito.Mockito.atLeastOnce;
34 import static org.mockito.Mockito.inOrder;
35 import static org.mockito.Mockito.mock;
36 import static org.mockito.Mockito.never;
37 import static org.mockito.Mockito.reset;
38 import static org.mockito.Mockito.verify;
39 import static org.mockito.Mockito.verifyNoMoreInteractions;
40 import static org.mockito.Mockito.when;
41 
42 import android.Manifest;
43 import android.app.test.TestAlarmManager;
44 import android.content.Context;
45 import android.content.pm.PackageManager;
46 import android.hardware.wifi.V1_0.NanStatusType;
47 import android.net.ConnectivityManager;
48 import android.net.MacAddress;
49 import android.net.NetworkCapabilities;
50 import android.net.NetworkFactory;
51 import android.net.NetworkProvider;
52 import android.net.NetworkRequest;
53 import android.net.NetworkSpecifier;
54 import android.net.wifi.WifiManager;
55 import android.net.wifi.aware.AttachCallback;
56 import android.net.wifi.aware.ConfigRequest;
57 import android.net.wifi.aware.DiscoverySession;
58 import android.net.wifi.aware.DiscoverySessionCallback;
59 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
60 import android.net.wifi.aware.IWifiAwareEventCallback;
61 import android.net.wifi.aware.IWifiAwareManager;
62 import android.net.wifi.aware.PeerHandle;
63 import android.net.wifi.aware.PublishConfig;
64 import android.net.wifi.aware.PublishDiscoverySession;
65 import android.net.wifi.aware.SubscribeConfig;
66 import android.net.wifi.aware.SubscribeDiscoverySession;
67 import android.net.wifi.aware.TlvBufferUtils;
68 import android.net.wifi.aware.WifiAwareManager;
69 import android.net.wifi.aware.WifiAwareNetworkInfo;
70 import android.net.wifi.aware.WifiAwareNetworkSpecifier;
71 import android.net.wifi.aware.WifiAwareSession;
72 import android.net.wifi.util.HexEncoding;
73 import android.os.Handler;
74 import android.os.Message;
75 import android.os.Messenger;
76 import android.os.PowerManager;
77 import android.os.Process;
78 import android.os.test.TestLooper;
79 
80 import androidx.test.filters.SmallTest;
81 
82 import com.android.server.wifi.Clock;
83 import com.android.server.wifi.MockResources;
84 import com.android.server.wifi.WifiBaseTest;
85 import com.android.server.wifi.aware.WifiAwareDataPathStateManager.WifiAwareNetworkAgent;
86 import com.android.server.wifi.util.NetdWrapper;
87 import com.android.server.wifi.util.WifiPermissionsUtil;
88 import com.android.server.wifi.util.WifiPermissionsWrapper;
89 import com.android.wifi.resources.R;
90 
91 import org.junit.After;
92 import org.junit.Before;
93 import org.junit.Rule;
94 import org.junit.Test;
95 import org.junit.rules.ErrorCollector;
96 import org.mockito.ArgumentCaptor;
97 import org.mockito.InOrder;
98 import org.mockito.Mock;
99 import org.mockito.MockitoAnnotations;
100 import org.mockito.Spy;
101 
102 import java.nio.ByteOrder;
103 import java.util.ArrayList;
104 import java.util.Arrays;
105 import java.util.Collections;
106 import java.util.HashSet;
107 import java.util.List;
108 import java.util.Set;
109 
110 
111 /**
112  * Unit test harness for WifiAwareDataPathStateManager class.
113  */
114 @SmallTest
115 public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
116     private static final String sAwareInterfacePrefix = "aware_data";
117     private static final String TEST_PACKAGE_NAME = "com.android.somePackage";
118     private static final String TEST_FEATURE_ID = "com.android.someFeature";
119 
120     private TestLooper mMockLooper;
121     private Handler mMockLooperHandler;
122     private WifiAwareStateManager mDut;
123     @Mock private Clock mClock;
124     @Mock private WifiAwareNativeManager mMockNativeManager;
125     @Spy private TestUtils.MonitoredWifiAwareNativeApi mMockNative =
126             new TestUtils.MonitoredWifiAwareNativeApi();
127     @Mock private Context mMockContext;
128     @Mock private ConnectivityManager mMockCm;
129     @Mock private NetdWrapper mMockNetdWrapper;
130     @Mock private WifiAwareDataPathStateManager.NetworkInterfaceWrapper mMockNetworkInterface;
131     @Mock private IWifiAwareEventCallback mMockCallback;
132     @Mock IWifiAwareDiscoverySessionCallback mMockSessionCallback;
133     @Mock private WifiAwareMetrics mAwareMetricsMock;
134     @Mock private WifiPermissionsUtil mWifiPermissionsUtil;
135     @Mock private WifiPermissionsWrapper mPermissionsWrapperMock;
136     @Mock private WifiManager mMockWifiManager;
137     TestAlarmManager mAlarmManager;
138     @Mock private PowerManager mMockPowerManager;
139 
140     @Rule
141     public ErrorCollector collector = new ErrorCollector();
142     private MockResources mResources;
143 
144     /**
145      * Initialize mocks.
146      */
147     @Before
setUp()148     public void setUp() throws Exception {
149         MockitoAnnotations.initMocks(this);
150 
151         mAlarmManager = new TestAlarmManager();
152         when(mMockContext.getSystemService(Context.ALARM_SERVICE))
153                 .thenReturn(mAlarmManager.getAlarmManager());
154 
155         when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
156         when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
157 
158         mMockLooper = new TestLooper();
159         mMockLooperHandler = new Handler(mMockLooper.getLooper());
160 
161         when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm);
162         when(mMockContext.getSystemService(ConnectivityManager.class)).thenReturn(mMockCm);
163         when(mMockContext.getSystemServiceName(PowerManager.class)).thenReturn(
164                 Context.POWER_SERVICE);
165         when(mMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager);
166 
167         // by default pretend to be an old API: i.e. allow Responders configured as *ANY*. This
168         // allows older (more extrensive) tests to run.
169         when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(), anyInt(), anyInt()))
170             .thenReturn(true);
171         when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
172 
173         mDut = new WifiAwareStateManager();
174         mDut.setNative(mMockNativeManager, mMockNative);
175         mDut.start(mMockContext, mMockLooper.getLooper(), mAwareMetricsMock,
176                 mWifiPermissionsUtil, mPermissionsWrapperMock, mClock, mMockNetdWrapper);
177         mDut.startLate();
178         mMockLooper.dispatchAll();
179 
180         when(mMockNetworkInterface.configureAgentProperties(any(), any(), any())).thenReturn(true);
181         when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(true);
182 
183         when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false);
184         when(mMockPowerManager.isInteractive()).thenReturn(true);
185 
186         mDut.mDataPathMgr.mNetdWrapper = mMockNetdWrapper;
187         mDut.mDataPathMgr.mNiWrapper = mMockNetworkInterface;
188 
189         mResources = new MockResources();
190         mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, false);
191         when(mMockContext.getResources()).thenReturn(mResources);
192     }
193 
194     /**
195      * Post-test validation.
196      */
197     @After
tearDown()198     public void tearDown() throws Exception {
199         mMockNative.validateUniqueTransactionIds();
200     }
201 
202     /**
203      * Validates that creating and deleting all interfaces works based on capabilities.
204      */
205     @Test
testCreateDeleteAllInterfaces()206     public void testCreateDeleteAllInterfaces() throws Exception {
207         final int numNdis = 3;
208         final int failCreateInterfaceIndex = 1;
209 
210         Capabilities capabilities = new Capabilities();
211         capabilities.maxNdiInterfaces = numNdis;
212 
213         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
214         ArgumentCaptor<String> interfaceName = ArgumentCaptor.forClass(String.class);
215         InOrder inOrder = inOrder(mMockNative);
216 
217         // (1) get capabilities
218         mDut.queryCapabilities();
219         mMockLooper.dispatchAll();
220         inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
221         mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities);
222         mMockLooper.dispatchAll();
223 
224         // (2) create all interfaces
225         mDut.createAllDataPathInterfaces();
226         mMockLooper.dispatchAll();
227         for (int i = 0; i < numNdis; ++i) {
228             inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(),
229                     interfaceName.capture());
230             collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i,
231                     equalTo(interfaceName.getValue()));
232             mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
233             mMockLooper.dispatchAll();
234         }
235 
236         // (3) delete all interfaces [one unsuccessfully] - note that will not necessarily be
237         // done sequentially
238         boolean[] done = new boolean[numNdis];
239         Arrays.fill(done, false);
240         mDut.deleteAllDataPathInterfaces();
241         mMockLooper.dispatchAll();
242         for (int i = 0; i < numNdis; ++i) {
243             inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(),
244                     interfaceName.capture());
245             int interfaceIndex = Integer.valueOf(
246                     interfaceName.getValue().substring(sAwareInterfacePrefix.length()));
247             done[interfaceIndex] = true;
248             if (interfaceIndex == failCreateInterfaceIndex) {
249                 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), false, 0);
250             } else {
251                 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0);
252             }
253             mMockLooper.dispatchAll();
254         }
255         verify(mMockNativeManager, never()).releaseAware();
256         for (int i = 0; i < numNdis; ++i) {
257             collector.checkThat("interface deleted -- " + i, done[i], equalTo(true));
258         }
259 
260         // (4) create all interfaces (should get a delete for the one which couldn't delete earlier)
261         mDut.createAllDataPathInterfaces();
262         mMockLooper.dispatchAll();
263         for (int i = 0; i < numNdis; ++i) {
264             if (i == failCreateInterfaceIndex) {
265                 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(),
266                         interfaceName.capture());
267                 collector.checkThat("interface delete pre-create -- " + i,
268                         sAwareInterfacePrefix + i, equalTo(interfaceName.getValue()));
269                 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0);
270                 mMockLooper.dispatchAll();
271             }
272             inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(),
273                     interfaceName.capture());
274             collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i,
275                     equalTo(interfaceName.getValue()));
276             mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
277             mMockLooper.dispatchAll();
278         }
279 
280         verifyNoMoreInteractions(mMockNative, mMockNetdWrapper);
281     }
282 
283     /**
284      * Validate that trying to specify port info on subscriber results in failure.
285      */
286     @Test
testDataPathWithPortInfoOnPublisher()287     public void testDataPathWithPortInfoOnPublisher() throws Exception {
288         final int clientId = 123;
289         final byte pubSubId = 55;
290         final int requestorId = 1341234;
291         final String passphrase = "SomeSecurePassword";
292         final int ndpId = 1;
293         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
294 
295         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
296         InOrder inOrderM = inOrder(mAwareMetricsMock);
297 
298         // (0) initialize
299         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
300                 peerDiscoveryMac, inOrder, inOrderM, false);
301 
302         // (1) request network
303         NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
304                 null, passphrase, true, 0, 5, 6);
305 
306         Message reqNetworkMsg = Message.obtain();
307         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
308         reqNetworkMsg.obj = nr;
309         reqNetworkMsg.arg1 = 0;
310         res.mMessenger.send(reqNetworkMsg);
311         mMockLooper.dispatchAll();
312         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
313 
314         // (2) provide a request
315         mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
316         mMockLooper.dispatchAll();
317 
318         // do not respond/create a data-path!
319         verify(mMockNative, never()).respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(),
320                 anyString(), any(), anyString(), any(), anyBoolean(), any());
321     }
322 
323     /**
324      * Validate that trying to specify invalid port info results in failure.
325      */
326     @Test
testDataPathWithPortInfoInvalidPort()327     public void testDataPathWithPortInfoInvalidPort() throws Exception {
328         final int clientId = 123;
329         final byte pubSubId = 55;
330         final int requestorId = 1341234;
331         final String passphrase = "SomeSecurePassword";
332         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
333 
334         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
335         InOrder inOrderM = inOrder(mAwareMetricsMock);
336 
337         // (0) initialize
338         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
339                 peerDiscoveryMac, inOrder, inOrderM, false);
340 
341         // (1) request network
342         NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
343                 null, passphrase, false, 0, -3, 6);
344 
345         Message reqNetworkMsg = Message.obtain();
346         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
347         reqNetworkMsg.obj = nr;
348         reqNetworkMsg.arg1 = 0;
349         res.mMessenger.send(reqNetworkMsg);
350         mMockLooper.dispatchAll();
351         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
352 
353         // do not create a data-path!
354         verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
355                 any(), anyString(), any(), anyString(), anyBoolean(), any(), any());
356     }
357 
358     /**
359      * Validate that trying to specify port info without security results in failure.
360      */
361     @Test
testDataPathWithPortInfoButNoSecurityOnSubscriber()362     public void testDataPathWithPortInfoButNoSecurityOnSubscriber() throws Exception {
363         final int clientId = 123;
364         final byte pubSubId = 55;
365         final int requestorId = 1341234;
366         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
367 
368         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
369         InOrder inOrderM = inOrder(mAwareMetricsMock);
370 
371         // (0) initialize
372         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
373                 peerDiscoveryMac, inOrder, inOrderM, false);
374 
375         // (1) request network
376         NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
377                 null, null, false, 0, 10, 6);
378 
379         Message reqNetworkMsg = Message.obtain();
380         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
381         reqNetworkMsg.obj = nr;
382         reqNetworkMsg.arg1 = 0;
383         res.mMessenger.send(reqNetworkMsg);
384         mMockLooper.dispatchAll();
385         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
386 
387         // do not create a data-path!
388         verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
389                 any(), anyString(), any(), anyString(), anyBoolean(), any(), any());
390     }
391 
392     /**
393      * Validate that if the data-interfaces are deleted while a data-path is being created, the
394      * process will terminate.
395      */
396     @Test
testDestroyNdiDuringNdpSetupResponder()397     public void testDestroyNdiDuringNdpSetupResponder() throws Exception {
398         final int clientId = 123;
399         final byte pubSubId = 55;
400         final int requestorId = 1341234;
401         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
402         final int ndpId = 3;
403 
404         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
405         InOrder inOrderM = inOrder(mAwareMetricsMock);
406 
407         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
408 
409         // (0) initialize
410         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
411                 peerDiscoveryMac, inOrder, inOrderM, true);
412 
413         // (1) request network
414         NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle,
415                 null, null, true, 0);
416 
417         Message reqNetworkMsg = Message.obtain();
418         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
419         reqNetworkMsg.obj = nr;
420         reqNetworkMsg.arg1 = 0;
421         res.mMessenger.send(reqNetworkMsg);
422         mMockLooper.dispatchAll();
423         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
424                 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB);
425 
426         // (2) delete interface(s)
427         mDut.deleteAllDataPathInterfaces();
428         mMockLooper.dispatchAll();
429         inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(),
430                 anyString());
431         mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0);
432         mMockLooper.dispatchAll();
433 
434         // (3) have responder receive request
435         mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
436         mMockLooper.dispatchAll();
437 
438         // (4) verify that responder aborts (i.e. refuses request)
439         inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(false),
440                 eq(ndpId), eq(""), eq(null), eq(null), eq(null), eq(false), any());
441         mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
442         mMockLooper.dispatchAll();
443 
444         verifyRequestDeclaredUnfullfillable(nr);
445 
446         // failure if there's further activity
447         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
448     }
449 
450     /**
451      * Validate multiple NDPs created on a single NDI when overlay set to enabled multiple NDP on
452      * same aware NDI. Most importantly that the interface is set up on first NDP and torn down on
453      * last NDP - and not when one or the other is created or deleted.
454      *
455      * Procedure:
456      * - create NDP 1, 2, and 3 (interface up only on first)
457      * - delete NDP 2, 1, and 3 (interface down only on last)
458      */
459     @Test
testMultipleNdpsOnSingleNdi()460     public void testMultipleNdpsOnSingleNdi() throws Exception {
461         final int clientId = 123;
462         final byte pubSubId = 58;
463         final int requestorId = 1341234;
464         final int ndpId = 2;
465         final String interfaceName = sAwareInterfacePrefix + "0";
466         final int port = 23;
467         final byte transportProtocol = 6;
468 
469         final int[] startOrder = {0, 1, 2};
470         final int[] endOrder = {1, 0, 2};
471         int networkRequestId = 0;
472 
473         mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, true);
474 
475         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor =
476                 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class);
477         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
478         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
479                 mMockNetdWrapper, mMockNetworkInterface);
480         InOrder inOrderM = inOrder(mAwareMetricsMock);
481 
482         NetworkRequest[] nrs = new NetworkRequest[3];
483         DataPathEndPointInfo[] ress = new DataPathEndPointInfo[3];
484         WifiAwareNetworkAgent[] agentBinders = new WifiAwareNetworkAgent[3];
485         Messenger messenger = null;
486         boolean first = true;
487         for (int i : startOrder) {
488             networkRequestId += 1;
489             byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
490             byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
491             peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i);
492             peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i);
493 
494             // (0) initialize
495             ress[i] = initDataPathEndPoint(first, clientId, (byte) (pubSubId + i),
496                     requestorId + i, peerDiscoveryMac, inOrder, inOrderM, false);
497             if (first) {
498                 messenger = ress[i].mMessenger;
499             }
500 
501             // (1) request network
502             nrs[i] = getSessionNetworkRequest(clientId, ress[i].mSessionId, ress[i].mPeerHandle,
503                     null, null, false, networkRequestId);
504 
505             Message reqNetworkMsg = Message.obtain();
506             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
507             reqNetworkMsg.obj = nrs[i];
508             reqNetworkMsg.arg1 = 0;
509             messenger.send(reqNetworkMsg);
510             mMockLooper.dispatchAll();
511             inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
512                     WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB);
513             inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
514                     eq(requestorId + i),
515                     eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
516                     eq(interfaceName), eq(null),
517                     eq(null), eq(false), any(), any());
518 
519             mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
520             mMockLooper.dispatchAll();
521 
522             // (2) get confirmation
523             mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0,
524                     buildTlv(port, transportProtocol, true), null);
525             mMockLooper.dispatchAll();
526             if (first) {
527                 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
528                 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
529 
530                 first = false;
531             }
532             inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
533             agentBinders[i] = agentCaptor.getValue();
534             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
535                     eq(false), anyLong());
536             inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
537             WifiAwareNetworkInfo netInfo =
538                     (WifiAwareNetworkInfo) agentBinders[i].mDataPathCapabilities.getTransportInfo();
539             assertArrayEquals(MacAddress.fromBytes(
540                     peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
541                     netInfo.getPeerIpv6Addr().getAddress());
542             assertEquals(port, netInfo.getPort());
543             assertEquals(transportProtocol, netInfo.getTransportProtocol());
544             assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps());
545         }
546 
547         // (3) end data-path (unless didn't get confirmation)
548         int index = 0;
549         for (int i: endOrder) {
550             Message endNetworkReqMsg = Message.obtain();
551             endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
552             endNetworkReqMsg.obj = nrs[i];
553             messenger.send(endNetworkReqMsg);
554 
555             agentBinders[i].onNetworkUnwanted();
556             mMockLooper.dispatchAll();
557 
558             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId + i));
559 
560             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
561             mDut.onDataPathEndNotification(ndpId + i);
562             mMockLooper.dispatchAll();
563 
564             if (index++ == endOrder.length - 1) {
565                 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString());
566             }
567             inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
568         }
569 
570         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
571     }
572 
573     /**
574      * Validate that multiple NDP requests which resolve to the same canonical request are treated
575      * as one.
576      */
577     @Test
testMultipleIdenticalRequests()578     public void testMultipleIdenticalRequests() throws Exception {
579         final int numRequestsPre = 6;
580         final int numRequestsPost = 5;
581         final int clientId = 123;
582         final int ndpId = 5;
583         final int port = 0;
584         final int transportProtocol = 6; // can't specify transport protocol without port
585         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
586         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
587         final byte[] allZeros = HexEncoding.decode("000000000000".toCharArray(), false);
588         NetworkRequest[] nrs = new NetworkRequest[numRequestsPre + numRequestsPost + 1];
589 
590         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
591         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor =
592                 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class);
593         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
594                 mMockNetdWrapper, mMockNetworkInterface);
595         InOrder inOrderM = inOrder(mAwareMetricsMock);
596 
597         // (1) initialize all clients
598         Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM);
599         for (int i = 1; i < numRequestsPre + numRequestsPost; ++i) {
600             initOobDataPathEndPoint(false, 1, clientId + i, inOrder, inOrderM);
601         }
602         DataPathEndPointInfo ddepi = initDataPathEndPoint(false,
603                 clientId + numRequestsPre + numRequestsPost, (byte) 10, 11, peerDiscoveryMac,
604                 inOrder, inOrderM, false);
605 
606         // (2) make initial network requests (all identical under the hood)
607         for (int i = 0; i < numRequestsPre; ++i) {
608             nrs[i] = getDirectNetworkRequest(clientId + i,
609                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null,
610                     null, i);
611 
612             Message reqNetworkMsg = Message.obtain();
613             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
614             reqNetworkMsg.obj = nrs[i];
615             reqNetworkMsg.arg1 = 0;
616             messenger.send(reqNetworkMsg);
617         }
618         mMockLooper.dispatchAll();
619         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
620 
621         // (3) verify the start NDP HAL request
622         inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
623                 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
624                 eq(sAwareInterfacePrefix + "0"), eq(null), eq(null), eq(true), any(), any());
625 
626         // (4) unregister request #0 (the primary)
627         Message endNetworkReqMsg = Message.obtain();
628         endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
629         endNetworkReqMsg.obj = nrs[0];
630         messenger.send(endNetworkReqMsg);
631         mMockLooper.dispatchAll();
632 
633         // (5) respond to the registration request
634         mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId);
635         mMockLooper.dispatchAll();
636 
637         // (6) unregister request #1
638         endNetworkReqMsg = Message.obtain();
639         endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
640         endNetworkReqMsg.obj = nrs[1];
641         messenger.send(endNetworkReqMsg);
642         mMockLooper.dispatchAll();
643 
644         // (6.5) provide a (semi) bogus NDP Requst Indication - mostly bogus on Initiator but
645         // may contain the peer's TLVs (in this case it does)
646         mDut.onDataPathRequestNotification(0, allZeros, ndpId,
647                 buildTlv(port, transportProtocol, true));
648 
649         // (7) confirm the NDP creation
650         mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null);
651         mMockLooper.dispatchAll();
652 
653         inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
654         inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
655         inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
656         inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
657                 eq(true), anyLong());
658         inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
659         WifiAwareNetworkInfo netInfo =
660                 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
661                         .getTransportInfo();
662         assertArrayEquals(MacAddress.fromBytes(
663                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
664                 netInfo.getPeerIpv6Addr().getAddress());
665         assertEquals(port, netInfo.getPort());
666         assertEquals(transportProtocol, netInfo.getTransportProtocol());
667         assertEquals(1, mDut.mDataPathMgr.getNumOfNdps());
668 
669         // (8) execute 'post' requests
670         for (int i = numRequestsPre; i < numRequestsPre + numRequestsPost; ++i) {
671             nrs[i] = getDirectNetworkRequest(clientId + i,
672                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null,
673                     null, i);
674 
675             Message reqNetworkMsg = Message.obtain();
676             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
677             reqNetworkMsg.obj = nrs[i];
678             reqNetworkMsg.arg1 = 0;
679             messenger.send(reqNetworkMsg);
680         }
681 
682         nrs[numRequestsPre + numRequestsPost] = getSessionNetworkRequest(
683                 clientId + numRequestsPre + numRequestsPost, ddepi.mSessionId, ddepi.mPeerHandle,
684                 null, null, false, 11);
685         Message reqNetworkMsg = Message.obtain();
686         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
687         reqNetworkMsg.obj = nrs[numRequestsPre + numRequestsPost];
688         reqNetworkMsg.arg1 = 0;
689         messenger.send(reqNetworkMsg);
690         mMockLooper.dispatchAll();
691         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
692 
693         // (9) unregister all requests
694         for (int i = 2; i < numRequestsPre + numRequestsPost + 1; ++i) {
695             endNetworkReqMsg = Message.obtain();
696             endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
697             endNetworkReqMsg.obj = nrs[i];
698             messenger.send(endNetworkReqMsg);
699             mMockLooper.dispatchAll();
700         }
701 
702         agentCaptor.getValue().onNetworkUnwanted();
703         mMockLooper.dispatchAll();
704 
705         // (10) verify that NDP torn down
706         inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
707 
708         mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
709         mDut.onDataPathEndNotification(ndpId);
710         mMockLooper.dispatchAll();
711 
712         inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString());
713         inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
714 
715         verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback,
716                 mAwareMetricsMock, mMockNetdWrapper);
717     }
718 
719     /**
720      * Validate that multiple NDP requests to the same peer target different NDIs.
721      */
722     @Test
testMultipleNdiToSamePeer()723     public void testMultipleNdiToSamePeer() throws Exception {
724         final int numNdis = 5;
725         final int clientId = 123;
726         final int ndpId = 5;
727         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
728         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
729 
730         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
731         ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class);
732         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass(
733                 WifiAwareNetworkAgent.class);
734 
735         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
736                 mMockNetdWrapper, mMockNetworkInterface);
737         InOrder inOrderM = inOrder(mAwareMetricsMock);
738 
739         // (1) initialize all clients
740         Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM);
741         for (int i = 1; i < numNdis + 3; ++i) {
742             initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM);
743         }
744 
745         // (2) make N network requests: each unique
746         Set<String> interfaces = new HashSet<>();
747         for (int i = 0; i < numNdis + 1; ++i) {
748             byte[] pmk = new byte[32];
749             pmk[0] = (byte) i;
750 
751             NetworkRequest nr = getDirectNetworkRequest(clientId + i,
752                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk,
753                     null, i);
754 
755             Message reqNetworkMsg = Message.obtain();
756             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
757             reqNetworkMsg.obj = nr;
758             reqNetworkMsg.arg1 = 0;
759             messenger.send(reqNetworkMsg);
760             mMockLooper.dispatchAll();
761             inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
762                     WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
763 
764             if (i < numNdis) {
765                 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
766                         eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
767                         ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any());
768                 interfaces.add(ifNameCaptor.getValue());
769 
770                 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
771                 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null);
772                 mMockLooper.dispatchAll();
773 
774                 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
775                 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
776                 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
777                 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
778                         eq(true), anyLong());
779                 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
780                 WifiAwareNetworkInfo netInfo =
781                         (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
782                                 .getTransportInfo();
783                 assertArrayEquals(MacAddress.fromBytes(
784                         peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
785                         netInfo.getPeerIpv6Addr().getAddress());
786                 assertEquals(0, netInfo.getPort()); // uninitialized -> 0
787                 assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1
788                 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps());
789             } else {
790                 verifyRequestDeclaredUnfullfillable(nr);
791             }
792         }
793 
794         // verify that each interface name is unique
795         assertEquals("Number of unique interface names", numNdis, interfaces.size());
796 
797         verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback,
798                 mAwareMetricsMock, mMockNetdWrapper);
799     }
800 
801     /**
802      * When overlay set to disabled multiple networks on single Aware NDI, validate that multiple
803      * NDP requests to the different peer target different NDIs. And when number of requests exceeds
804      * the number of NDIs, request will be rejected.
805      */
806     @Test
testMultipleNdiToDifferentPeer()807     public void testMultipleNdiToDifferentPeer() throws Exception {
808         final int numNdis = 5;
809         final int clientId = 123;
810         final int ndpId = 5;
811 
812         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
813         ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class);
814         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass(
815                 WifiAwareNetworkAgent.class);
816 
817         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
818                 mMockNetdWrapper, mMockNetworkInterface);
819         InOrder inOrderM = inOrder(mAwareMetricsMock);
820 
821         // (1) initialize all clients
822         Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM);
823         for (int i = 1; i < numNdis + 3; ++i) {
824             initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM);
825         }
826 
827         // (2) make N network requests: each unique
828         Set<String> interfaces = new HashSet<>();
829         for (int i = 0; i < numNdis + 1; ++i) {
830             final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
831             final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
832             peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i);
833             peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i);
834 
835             byte[] pmk = new byte[32];
836             pmk[0] = (byte) i;
837 
838             NetworkRequest nr = getDirectNetworkRequest(clientId + i,
839                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk,
840                     null, i);
841 
842             Message reqNetworkMsg = Message.obtain();
843             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
844             reqNetworkMsg.obj = nr;
845             reqNetworkMsg.arg1 = 0;
846             messenger.send(reqNetworkMsg);
847             mMockLooper.dispatchAll();
848             inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
849                     WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
850 
851             if (i < numNdis) {
852                 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
853                         eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
854                         ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any());
855                 interfaces.add(ifNameCaptor.getValue());
856 
857                 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
858                 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null);
859                 mMockLooper.dispatchAll();
860 
861                 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
862                 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
863                 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
864                 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
865                         eq(true), anyLong());
866                 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
867                 WifiAwareNetworkInfo netInfo =
868                         (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
869                                 .getTransportInfo();
870                 assertArrayEquals(MacAddress.fromBytes(
871                         peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
872                         netInfo.getPeerIpv6Addr().getAddress());
873                 assertEquals(0, netInfo.getPort()); // uninitialized -> 0
874                 assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1
875                 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps());
876             } else {
877                 verifyRequestDeclaredUnfullfillable(nr);
878             }
879         }
880 
881         // verify that each interface name is unique
882         assertEquals("Number of unique interface names", numNdis, interfaces.size());
883 
884         verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback,
885                 mAwareMetricsMock, mMockNetdWrapper);
886     }
887 
888     /**
889      * When overlay set to enable multiple networks on single Aware NDI, validate that multiple
890      * NDP requests to the different peer target same NDI when only one NDI is available. Also when
891      * requests to a peer that is already accepted by this NDI, the new request should be reject.
892      */
893     @Test
testMultipleNdpToDifferentPeerOnSingleNdi()894     public void testMultipleNdpToDifferentPeerOnSingleNdi() throws Exception {
895         final int numNdis = 1;
896         final int clientId = 123;
897         final int ndpId = 5;
898         final int numberNdp = 3;
899 
900         mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, true);
901 
902         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
903         ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class);
904         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass(
905                 WifiAwareNetworkAgent.class);
906 
907         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
908                 mMockNetdWrapper, mMockNetworkInterface);
909         InOrder inOrderM = inOrder(mAwareMetricsMock);
910 
911         // (1) initialize all clients
912         Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM);
913         for (int i = 1; i < numberNdp; ++i) {
914             initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM);
915         }
916 
917         // (2) make 2 network requests: each unique
918         Set<String> interfaces = new HashSet<>();
919         boolean first = true;
920         for (int i = 0; i < numberNdp - 1; ++i) {
921             final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
922             final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
923             peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i);
924             peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i);
925 
926             byte[] pmk = new byte[32];
927             pmk[0] = (byte) i;
928 
929             NetworkRequest nr = getDirectNetworkRequest(clientId + i,
930                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk,
931                     null, i);
932 
933             Message reqNetworkMsg = Message.obtain();
934             reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
935             reqNetworkMsg.obj = nr;
936             reqNetworkMsg.arg1 = 0;
937             messenger.send(reqNetworkMsg);
938             mMockLooper.dispatchAll();
939             inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
940                     WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
941 
942             inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
943                     eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
944                     ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any());
945             interfaces.add(ifNameCaptor.getValue());
946 
947             mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
948             mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null);
949             mMockLooper.dispatchAll();
950             if (first) {
951                 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
952                 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
953                 first = false;
954             }
955             inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
956             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
957                     eq(true), anyLong());
958             inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
959             WifiAwareNetworkInfo netInfo =
960                     (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
961                             .getTransportInfo();
962             assertArrayEquals(MacAddress.fromBytes(
963                     peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
964                     netInfo.getPeerIpv6Addr().getAddress());
965             assertEquals(0, netInfo.getPort()); // uninitialized -> 0
966             assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1
967             assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps());
968         }
969 
970         // verify that two request all using the same interface
971         assertEquals("Number of unique interface names", numNdis, interfaces.size());
972 
973 
974         // make the 3rd network request which has the same peer as the first one.
975         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
976 
977         byte[] pmk = new byte[32];
978         pmk[0] = (byte) 2;
979 
980         NetworkRequest nr = getDirectNetworkRequest(clientId + 2,
981                 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk,
982                 null, 2);
983 
984         Message reqNetworkMsg = Message.obtain();
985         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
986         reqNetworkMsg.obj = nr;
987         reqNetworkMsg.arg1 = 0;
988         messenger.send(reqNetworkMsg);
989         mMockLooper.dispatchAll();
990         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
991                 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
992 
993         // It should be reject as interface already has a request to this peer.
994         verifyRequestDeclaredUnfullfillable(nr);
995 
996         verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback,
997                 mAwareMetricsMock, mMockNetdWrapper);
998     }
999 
1000     /*
1001      * Initiator tests
1002      */
1003 
1004     /**
1005      * Validate the success flow of the Initiator: using session network specifier with a non-null
1006      * PMK.
1007      */
1008     @Test
testDataPathInitiatorMacPmkSuccess()1009     public void testDataPathInitiatorMacPmkSuccess() throws Exception {
1010         testDataPathInitiatorUtility(false, true, true, false, true, false);
1011     }
1012 
1013     /**
1014      * Validate the success flow of the Initiator: using a direct network specifier with a non-null
1015      * peer mac and non-null PMK.
1016      */
1017     @Test
testDataPathInitiatorDirectMacPmkSuccess()1018     public void testDataPathInitiatorDirectMacPmkSuccess() throws Exception {
1019         testDataPathInitiatorUtility(true, true, true, false, true, false);
1020     }
1021 
1022 
1023     /**
1024      * Validate the fail flow of the Initiator: use a session network specifier with a non-null
1025      * PMK, but don't get a confirmation.
1026      */
1027     @Test
testDataPathInitiatorNoConfirmationTimeoutFail()1028     public void testDataPathInitiatorNoConfirmationTimeoutFail() throws Exception {
1029         testDataPathInitiatorUtility(false, true, true, false, false, false);
1030     }
1031 
1032     /**
1033      * Validate the fail flow of the Initiator: use a session network specifier with a non-null
1034      * Passphrase, but get an immediate failure
1035      */
1036     @Test
testDataPathInitiatorNoConfirmationHalFail()1037     public void testDataPathInitiatorNoConfirmationHalFail() throws Exception {
1038         testDataPathInitiatorUtility(false, true, false, true, true, true);
1039     }
1040 
1041     /**
1042      * Verify that an TLV configuration with large port/transport-protocol work correctly.
1043      */
1044     @Test
testDataPathInitiatorNetInfoLargeValuesExp1()1045     public void testDataPathInitiatorNetInfoLargeValuesExp1() throws Exception {
1046         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1047         String linkLocalIpv6Address = MacAddress.fromBytes(
1048                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1049 
1050         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1051                 buildTlv((1 << 16) - 1, (1 << 8) - 1, true), (1 << 16) - 1, (1 << 8) - 1,
1052                 linkLocalIpv6Address, 0);
1053     }
1054 
1055     /**
1056      * Verify that an TLV configuration with large port/transport-protocol work correctly.
1057      */
1058     @Test
testDataPathInitiatorNetInfoLargeValuesExp2()1059     public void testDataPathInitiatorNetInfoLargeValuesExp2() throws Exception {
1060         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1061         String linkLocalIpv6Address = MacAddress.fromBytes(
1062                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1063 
1064         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1065                 buildTlv(1 << 15, 1 << 7, true), 1 << 15, 1 << 7, linkLocalIpv6Address, 0);
1066     }
1067 
1068     /**
1069      * Verify that an TLV configuration with large port/transport-protocol work correctly.
1070      */
1071     @Test
testDataPathInitiatorNetInfoLargeValuesExp3()1072     public void testDataPathInitiatorNetInfoLargeValuesExp3() throws Exception {
1073         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1074         String linkLocalIpv6Address = MacAddress.fromBytes(
1075                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1076 
1077         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1078                 buildTlv((1 << 15) - 1, (1 << 7) - 1, true), (1 << 15) - 1, (1 << 7) - 1,
1079                 linkLocalIpv6Address, 0);
1080     }
1081 
1082     /**
1083      * Verify that an TLV configuration with an IPv6 override works correctly.
1084      */
1085     @Test
testDataPathInitiatorNetInfoIpv6Override()1086     public void testDataPathInitiatorNetInfoIpv6Override() throws Exception {
1087         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1088         final byte[] testVector =
1089                 new byte[]{0x00, 0x08, 0x00, 0x00, (byte) 0xb3, (byte) 0xe1, (byte) 0xff,
1090                         (byte) 0xfe, 0x7a, 0x2f, (byte) 0xa2};
1091 
1092         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1093                 testVector, 0, -1, "fe80::b3:e1ff:fe7a:2fa2", 0);
1094     }
1095 
1096     /**
1097      * Verify that retrying address validation a 'small' number of times results in successful
1098      * NDP setup.
1099      */
1100     @Test
testDataPathInitiatorAddressValidationRetrySuccess()1101     public void testDataPathInitiatorAddressValidationRetrySuccess() throws Exception {
1102         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1103         String linkLocalIpv6Address = MacAddress.fromBytes(
1104                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1105 
1106         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1107                 null, 0, -1, linkLocalIpv6Address,
1108                 WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS
1109                         / WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS - 1);
1110     }
1111 
1112     /**
1113      * Verify that retrying address validation a 'large' number of times results in failure.
1114      */
1115     @Test
testDataPathInitiatorAddressValidationRetryFail()1116     public void testDataPathInitiatorAddressValidationRetryFail() throws Exception {
1117         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1118         String linkLocalIpv6Address = MacAddress.fromBytes(
1119                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1120 
1121         testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac,
1122                 null, 0, -1, linkLocalIpv6Address,
1123                 WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS
1124                         / WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS + 10);
1125     }
1126 
1127     /**
1128      * Validate the fail flow of a mis-configured request: Publisher as Initiator
1129      */
1130     @Test
testDataPathInitiatorOnPublisherError()1131     public void testDataPathInitiatorOnPublisherError() throws Exception {
1132         testDataPathInitiatorResponderMismatchUtility(true);
1133     }
1134 
1135     /**
1136      * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious
1137      * attacker (i.e. mismatched to its requested client's UID).
1138      */
1139     @Test
testDataPathInitiatorUidSetIncorrectlyError()1140     public void testDataPathInitiatorUidSetIncorrectlyError() throws Exception {
1141         testDataPathInitiatorResponderInvalidUidUtility(false);
1142     }
1143 
1144     /**
1145      * Validate the fail flow of an Initiator (subscriber) with its package namee set as a malicious
1146      * attacker (i.e. mismatched to its requested client's package name).
1147      */
1148     @Test
testDataPathInitiatorPackageNameSetIncorrectlyError()1149     public void testDataPathInitiatorPackageNameSetIncorrectlyError() throws Exception {
1150         testDataPathInitiatorResponderInvalidPackageNameUtility(false);
1151     }
1152 
1153     /*
1154      * Responder tests
1155      */
1156 
1157     /**
1158      * Validate the success flow of the Responder: using session network specifier with a
1159      * PMK.
1160      */
1161     @Test
testDataPathResonderMacPmkSuccess()1162     public void testDataPathResonderMacPmkSuccess() throws Exception {
1163         testDataPathResponderUtility(false, true, true, false, true);
1164     }
1165 
1166     /**
1167      * Validate the success flow of the Responder: using session network specifier with a
1168      * Passphrase.
1169      */
1170     @Test
testDataPathResonderMacPassphraseSuccess()1171     public void testDataPathResonderMacPassphraseSuccess() throws Exception {
1172         testDataPathResponderUtility(false, true, false, false, true);
1173     }
1174 
1175     /**
1176      * Validate the success flow of the Responder: using session network specifier with a
1177      * Passphrase and no peer ID (i.e. 0).
1178      */
1179     @Test
testDataPathResonderMacPassphraseNoPeerIdSuccess()1180     public void testDataPathResonderMacPassphraseNoPeerIdSuccess() throws Exception {
1181         testDataPathResponderUtility(false, false, false, true, true);
1182     }
1183 
1184     /**
1185      * Validate the success flow of the Responder: using session network specifier with a null
1186      * PMK/Passphrase and no peer ID (i.e. 0).
1187      */
1188     @Test
testDataPathResonderMacOpenNoPeerIdNoPmkPassphraseSuccess()1189     public void testDataPathResonderMacOpenNoPeerIdNoPmkPassphraseSuccess() throws Exception {
1190         testDataPathResponderUtility(false, false, false, false, true);
1191     }
1192 
1193     /**
1194      * Validate the success flow of the Responder: using a direct network specifier with a non-null
1195      * peer mac and non-null PMK.
1196      */
1197     @Test
testDataPathResonderDirectMacPmkSuccess()1198     public void testDataPathResonderDirectMacPmkSuccess() throws Exception {
1199         testDataPathResponderUtility(true, true, true, false, true);
1200     }
1201 
1202     /**
1203      * Validate the success flow of the Responder: using a direct network specifier with a non-null
1204      * peer mac and null PMK/Passphrase.
1205      */
1206     @Test
testDataPathResonderDirectMacNoPmkPassphraseSuccess()1207     public void testDataPathResonderDirectMacNoPmkPassphraseSuccess() throws Exception {
1208         testDataPathResponderUtility(true, true, false, false, true);
1209     }
1210 
1211     /**
1212      * Validate the success flow of the Responder: using a direct network specifier with a null peer
1213      * mac and non-null Passphrase.
1214      */
1215     @Test
testDataPathResonderDirectNoMacPassphraseSuccess()1216     public void testDataPathResonderDirectNoMacPassphraseSuccess() throws Exception {
1217         testDataPathResponderUtility(true, false, false, true, true);
1218     }
1219 
1220     /**
1221      * Validate the success flow of the Responder: using a direct network specifier with a null peer
1222      * mac and null Pmk/Passphrase.
1223      */
1224     @Test
testDataPathResonderDirectNoMacNoPmkPassphraseSuccess()1225     public void testDataPathResonderDirectNoMacNoPmkPassphraseSuccess() throws Exception {
1226         testDataPathResponderUtility(true, false, false, false, true);
1227     }
1228 
1229     /**
1230      * Validate the fail flow of the Responder: use a session network specifier with a non-null
1231      * PMK, but don't get a confirmation.
1232      */
1233     @Test
testDataPathResponderNoConfirmationTimeoutFail()1234     public void testDataPathResponderNoConfirmationTimeoutFail() throws Exception {
1235         testDataPathResponderUtility(false, true, true, false, false);
1236     }
1237 
1238     /**
1239      * Validate the fail flow of a mis-configured request: Subscriber as Responder
1240      */
1241     @Test
testDataPathResponderOnSubscriberError()1242     public void testDataPathResponderOnSubscriberError() throws Exception {
1243         testDataPathInitiatorResponderMismatchUtility(false);
1244     }
1245 
1246     /**
1247      * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious
1248      * attacker (i.e. mismatched to its requested client's UID).
1249      */
1250     @Test
testDataPathResponderUidSetIncorrectlyError()1251     public void testDataPathResponderUidSetIncorrectlyError() throws Exception {
1252         testDataPathInitiatorResponderInvalidUidUtility(true);
1253     }
1254 
1255 
1256     /**
1257      * Validate the fail flow of an Initiator (subscriber) with its package name set as a malicious
1258      * attacker (i.e. mismatched to its requested client's package name).
1259      */
1260     @Test
testDataPathResponderPackageNameSetIncorrectlyError()1261     public void testDataPathResponderPackageNameSetIncorrectlyError() throws Exception {
1262         testDataPathInitiatorResponderInvalidPackageNameUtility(true);
1263     }
1264 
1265     /**
1266      * Validate the TLV generation based on a test vector manually generated from spec.
1267      */
1268     @Test
testTlvGenerationTestVectorPortTransportProtocol()1269     public void testTlvGenerationTestVectorPortTransportProtocol() {
1270         int port = 7000;
1271         int transportProtocol = 6;
1272 
1273         byte[] tlvData = WifiAwareDataPathStateManager.NetworkInformationData.buildTlv(port,
1274                 transportProtocol);
1275         byte[] testVector =
1276                 new byte[]{0x01, 0x0d, 0x00, 0x50, 0x6f, (byte) 0x9a, 0x02, 0x00, 0x02, 0x00, 0x58,
1277                         0x1b, 0x01, 0x01, 0x00, 0x06};
1278 
1279         assertArrayEquals(testVector, tlvData);
1280     }
1281 
1282     /**
1283      * Validate the TLV parsing based on a test vector of the port + transport protocol manually
1284      * generated from spec.
1285      */
1286     @Test
testTlvParsingTestVectorPortTransportProtocol()1287     public void testTlvParsingTestVectorPortTransportProtocol() {
1288         int port = 7000;
1289         int transportProtocol = 6;
1290 
1291         byte[] testVector =
1292                 new byte[]{0x01, 0x0d, 0x00, 0x50, 0x6f, (byte) 0x9a, 0x02, 0x00, 0x02, 0x00, 0x58,
1293                         0x1b, 0x01, 0x01, 0x00, 0x06};
1294 
1295         WifiAwareDataPathStateManager.NetworkInformationData.ParsedResults parsed =
1296                 WifiAwareDataPathStateManager.NetworkInformationData.parseTlv(testVector);
1297         assertEquals(port, (int) parsed.port);
1298         assertEquals(transportProtocol, (int) parsed.transportProtocol);
1299     }
1300 
1301     /*
1302      * Utilities
1303      */
1304 
testDataPathInitiatorResponderMismatchUtility(boolean doPublish)1305     private void testDataPathInitiatorResponderMismatchUtility(boolean doPublish) throws Exception {
1306         final int clientId = 123;
1307         final byte pubSubId = 55;
1308         final int ndpId = 2;
1309         final byte[] pmk = "01234567890123456789012345678901".getBytes();
1310         final int requestorId = 1341234;
1311         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
1312 
1313         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
1314         InOrder inOrderM = inOrder(mAwareMetricsMock);
1315 
1316         // (0) initialize
1317         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
1318                 peerDiscoveryMac, inOrder, inOrderM, doPublish);
1319 
1320         // (1) request network
1321         NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk,
1322                 null, doPublish, 0);
1323 
1324         // corrupt the network specifier: reverse the role (so it's mis-matched)
1325         WifiAwareNetworkSpecifier ns =
1326                 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier();
1327         ns = new WifiAwareNetworkSpecifier(
1328                 ns.type,
1329                 1 - ns.role, // corruption hack
1330                 ns.clientId,
1331                 ns.sessionId,
1332                 ns.peerId,
1333                 ns.peerMac,
1334                 ns.pmk,
1335                 ns.passphrase,
1336                 0,
1337                 0);
1338         nr.networkCapabilities.setNetworkSpecifier(ns);
1339         nr.networkCapabilities.setRequestorUid(Process.myUid());
1340         nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME);
1341 
1342         Message reqNetworkMsg = Message.obtain();
1343         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
1344         reqNetworkMsg.obj = nr;
1345         reqNetworkMsg.arg1 = 0;
1346         res.mMessenger.send(reqNetworkMsg);
1347         mMockLooper.dispatchAll();
1348         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
1349 
1350         // consequences of failure:
1351         //   Responder (publisher): responds with a rejection to any data-path requests
1352         //   Initiator (subscribe): doesn't initiate (i.e. no HAL requests)
1353         verifyRequestDeclaredUnfullfillable(nr);
1354         if (doPublish) {
1355             // (2) get request & respond
1356             mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
1357             mMockLooper.dispatchAll();
1358             inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
1359                     eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any());
1360         }
1361 
1362         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
1363     }
1364 
testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish)1365     private void testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish)
1366             throws Exception {
1367         final int clientId = 123;
1368         final byte pubSubId = 56;
1369         final int ndpId = 2;
1370         final byte[] pmk = "01234567890123456789012345678901".getBytes();
1371         final int requestorId = 1341234;
1372         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
1373 
1374         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
1375         InOrder inOrderM = inOrder(mAwareMetricsMock);
1376 
1377         // (0) initialize
1378         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
1379                 peerDiscoveryMac, inOrder, inOrderM, doPublish);
1380 
1381         // (1) create network request
1382         NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk,
1383                 null, doPublish, 0);
1384 
1385         // (2) corrupt request's UID
1386         WifiAwareNetworkSpecifier ns =
1387                 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier();
1388         ns = new WifiAwareNetworkSpecifier(
1389                 ns.type,
1390                 ns.role,
1391                 ns.clientId,
1392                 ns.sessionId,
1393                 ns.peerId,
1394                 ns.peerMac,
1395                 ns.pmk,
1396                 ns.passphrase,
1397                 0,
1398                 0);
1399         nr.networkCapabilities.setNetworkSpecifier(ns);
1400         nr.networkCapabilities.setRequestorUid(0 + 1); // corruption hack
1401         nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME);
1402 
1403         // (3) request network
1404         Message reqNetworkMsg = Message.obtain();
1405         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
1406         reqNetworkMsg.obj = nr;
1407         reqNetworkMsg.arg1 = 0;
1408         res.mMessenger.send(reqNetworkMsg);
1409         mMockLooper.dispatchAll();
1410         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
1411 
1412 
1413         // consequences of failure:
1414         //   Responder (publisher): responds with a rejection to any data-path requests
1415         //   Initiator (subscribe): doesn't initiate (i.e. no HAL requests)
1416         verifyRequestDeclaredUnfullfillable(nr);
1417         if (doPublish) {
1418             // (2) get request & respond
1419             mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
1420             mMockLooper.dispatchAll();
1421             inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
1422                     eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any());
1423         }
1424 
1425         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
1426     }
1427 
testDataPathInitiatorResponderInvalidPackageNameUtility(boolean doPublish)1428     private void testDataPathInitiatorResponderInvalidPackageNameUtility(boolean doPublish)
1429             throws Exception {
1430         final int clientId = 123;
1431         final byte pubSubId = 56;
1432         final int ndpId = 2;
1433         final byte[] pmk = "01234567890123456789012345678901".getBytes();
1434         final int requestorId = 1341234;
1435         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
1436 
1437         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
1438         InOrder inOrderM = inOrder(mAwareMetricsMock);
1439 
1440         // (0) initialize
1441         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
1442                 peerDiscoveryMac, inOrder, inOrderM, doPublish);
1443 
1444         // (1) create network request
1445         NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk,
1446                 null, doPublish, 0);
1447 
1448         // (2) corrupt request's UID
1449         WifiAwareNetworkSpecifier ns =
1450                 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier();
1451         ns = new WifiAwareNetworkSpecifier(
1452                 ns.type,
1453                 ns.role,
1454                 ns.clientId,
1455                 ns.sessionId,
1456                 ns.peerId,
1457                 ns.peerMac,
1458                 ns.pmk,
1459                 ns.passphrase,
1460                 0,
1461                 0);
1462         nr.networkCapabilities.setNetworkSpecifier(ns);
1463         nr.networkCapabilities.setRequestorUid(Process.myUid()); // corruption hack
1464         nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME + "h"); // corruption hack
1465 
1466         // (3) request network
1467         Message reqNetworkMsg = Message.obtain();
1468         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
1469         reqNetworkMsg.obj = nr;
1470         reqNetworkMsg.arg1 = 0;
1471         res.mMessenger.send(reqNetworkMsg);
1472         mMockLooper.dispatchAll();
1473         inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt());
1474 
1475         // consequences of failure:
1476         //   Responder (publisher): responds with a rejection to any data-path requests
1477         //   Initiator (subscribe): doesn't initiate (i.e. no HAL requests)
1478         verifyRequestDeclaredUnfullfillable(nr);
1479         if (doPublish) {
1480             // (2) get request & respond
1481             mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
1482             mMockLooper.dispatchAll();
1483             inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
1484                     eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any());
1485         }
1486 
1487         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
1488     }
1489 
testDataPathInitiatorUtility(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation, boolean immediateHalFailure)1490     private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac,
1491             boolean providePmk, boolean providePassphrase, boolean getConfirmation,
1492             boolean immediateHalFailure) throws Exception {
1493         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1494         String linkLocalIpv6Address = MacAddress.fromBytes(
1495                 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress();
1496 
1497         testDataPathInitiatorUtilityMore(useDirect, provideMac, providePmk, providePassphrase,
1498                 getConfirmation, immediateHalFailure, peerDataPathMac, null, 0, -1,
1499                 linkLocalIpv6Address, 0);
1500     }
1501 
testDataPathInitiatorUtilityMore(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation, boolean immediateHalFailure, byte[] peerDataPathMac, byte[] peerToken, int port, int transportProtocol, String ipv6Address, int numAddrValidationRetries)1502     private void testDataPathInitiatorUtilityMore(boolean useDirect, boolean provideMac,
1503             boolean providePmk, boolean providePassphrase, boolean getConfirmation,
1504             boolean immediateHalFailure, byte[] peerDataPathMac, byte[] peerToken, int port,
1505             int transportProtocol, String ipv6Address, int numAddrValidationRetries)
1506             throws Exception {
1507         final int clientId = 123;
1508         final byte pubSubId = 58;
1509         final int requestorId = 1341234;
1510         final int ndpId = 2;
1511         final byte[] pmk = "01234567890123456789012345678901".getBytes();
1512         final String passphrase = "some passphrase";
1513         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
1514 
1515         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor =
1516                 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class);
1517         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1518         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
1519                 mMockNetdWrapper, mMockNetworkInterface);
1520         InOrder inOrderM = inOrder(mAwareMetricsMock);
1521         WifiAwareNetworkAgent networkAgent = null;
1522 
1523         if (!providePmk) {
1524             when(mPermissionsWrapperMock.getUidPermission(
1525                     eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn(
1526                     PackageManager.PERMISSION_DENIED);
1527         }
1528 
1529         if (immediateHalFailure) {
1530             when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), any(),
1531                     any(), any(), any(), anyBoolean(), any(), any())).thenReturn(false);
1532 
1533         }
1534 
1535         // (0) initialize
1536         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
1537                 peerDiscoveryMac, inOrder, inOrderM, false);
1538 
1539         // (1) request network
1540         NetworkRequest nr;
1541         if (useDirect) {
1542             nr = getDirectNetworkRequest(clientId,
1543                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR,
1544                     provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null,
1545                     providePassphrase ? passphrase : null, 0);
1546         } else {
1547             nr = getSessionNetworkRequest(clientId, res.mSessionId,
1548                     provideMac ? res.mPeerHandle : null, providePmk ? pmk : null,
1549                     providePassphrase ? passphrase : null, false, 0);
1550         }
1551 
1552         Message reqNetworkMsg = Message.obtain();
1553         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
1554         reqNetworkMsg.obj = nr;
1555         reqNetworkMsg.arg1 = 0;
1556         res.mMessenger.send(reqNetworkMsg);
1557         mMockLooper.dispatchAll();
1558         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
1559         inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
1560                 eq(useDirect ? 0 : requestorId),
1561                 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
1562                 eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
1563                 eq(providePassphrase ? passphrase : null), eq(useDirect), any(), any());
1564         if (immediateHalFailure) {
1565             // short-circuit the rest of this test
1566             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE),
1567                     eq(useDirect), anyLong());
1568             verifyRequestDeclaredUnfullfillable(nr);
1569             verifyNoMoreInteractions(mMockNative, mAwareMetricsMock);
1570             return;
1571         }
1572 
1573         mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId);
1574         mMockLooper.dispatchAll();
1575 
1576         // (2) get confirmation OR timeout
1577         boolean timeout = false;
1578         if (getConfirmation) {
1579             int numConfigureAgentPropertiesFail = 0;
1580             if (numAddrValidationRetries > 0) {
1581                 when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(false);
1582                 when(mMockNetworkInterface.configureAgentProperties(any(), any(), any()))
1583                         .thenReturn(false);
1584                 // First retry will be ConfigureAgentProperties failure.
1585                 numConfigureAgentPropertiesFail = 1;
1586             }
1587             when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
1588 
1589             mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, peerToken, null);
1590             mMockLooper.dispatchAll();
1591             inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
1592             inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
1593             inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(), any());
1594             if (numAddrValidationRetries <= 0) {
1595                 inOrder.verify(mMockNetworkInterface).isAddressUsable(any());
1596             }
1597             for (int i = 0; i < numAddrValidationRetries; ++i) {
1598                 if (i == numConfigureAgentPropertiesFail) {
1599                     when(mMockNetworkInterface.configureAgentProperties(any(), any(), any()))
1600                             .thenReturn(true);
1601                 }
1602                 if (i == numAddrValidationRetries - 1) {
1603                     when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(true);
1604                 }
1605                 long currentTime = (i + 1L)
1606                         * WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS;
1607                 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime);
1608                 mMockLooper.moveTimeForward(
1609                         WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS + 1);
1610                 mMockLooper.dispatchAll();
1611                 inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(), any());
1612                 if (i < numConfigureAgentPropertiesFail) {
1613                     continue;
1614                 }
1615                 inOrder.verify(mMockNetworkInterface).isAddressUsable(any());
1616                 if (currentTime > WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS) {
1617                     timeout = true;
1618                     break;
1619                 }
1620             }
1621             if (timeout) {
1622                 verifyRequestDeclaredUnfullfillable(nr);
1623                 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
1624                 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
1625             } else {
1626                 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
1627                 networkAgent = agentCaptor.getValue();
1628                 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
1629                         eq(useDirect), anyLong());
1630                 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
1631                 WifiAwareNetworkInfo netInfo =
1632                         (WifiAwareNetworkInfo) networkAgent.mDataPathCapabilities
1633                                 .getTransportInfo();
1634                 assertEquals(ipv6Address, netInfo.getPeerIpv6Addr().getHostAddress());
1635                 assertEquals(port, netInfo.getPort());
1636                 assertEquals(transportProtocol, netInfo.getTransportProtocol());
1637                 assertEquals(1, mDut.mDataPathMgr.getNumOfNdps());
1638                 mDut.onDataPathScheduleUpdateNotification(peerDiscoveryMac, new ArrayList<>(ndpId),
1639                         Collections.emptyList());
1640                 mMockLooper.dispatchAll();
1641             }
1642         } else {
1643             assertTrue(mAlarmManager.dispatch(
1644                     WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
1645             mMockLooper.dispatchAll();
1646             verifyRequestDeclaredUnfullfillable(nr);
1647             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
1648             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
1649             mMockLooper.dispatchAll();
1650             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE),
1651                     eq(useDirect), anyLong());
1652         }
1653 
1654         // (3) end data-path (unless didn't get confirmation)
1655         if (getConfirmation && !timeout) {
1656             Message endNetworkReqMsg = Message.obtain();
1657             endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
1658             endNetworkReqMsg.obj = nr;
1659             res.mMessenger.send(endNetworkReqMsg);
1660 
1661             networkAgent.onNetworkUnwanted();
1662             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
1663             mDut.onDataPathEndNotification(ndpId);
1664             mMockLooper.dispatchAll();
1665 
1666             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
1667             inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString());
1668             inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
1669         }
1670 
1671         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper,
1672                 mMockNetworkInterface);
1673     }
1674 
testDataPathResponderUtility(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation)1675     private void testDataPathResponderUtility(boolean useDirect, boolean provideMac,
1676             boolean providePmk, boolean providePassphrase, boolean getConfirmation)
1677             throws Exception {
1678         final int clientId = 123;
1679         final byte pubSubId = 60;
1680         final int requestorId = 1341234;
1681         final int ndpId = 2;
1682         final byte[] pmk = "01234567890123456789012345678901".getBytes();
1683         final String passphrase = "some passphrase";
1684         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
1685         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
1686 
1687         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor =
1688                 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class);
1689         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1690         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback,
1691                 mMockNetdWrapper, mMockNetworkInterface);
1692         InOrder inOrderM = inOrder(mAwareMetricsMock);
1693 
1694         if (providePmk) {
1695             when(mPermissionsWrapperMock.getUidPermission(
1696                     eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn(
1697                     PackageManager.PERMISSION_GRANTED);
1698         }
1699 
1700         // (0) initialize
1701         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
1702                 peerDiscoveryMac, inOrder, inOrderM, true);
1703 
1704         // (1) request network
1705         NetworkRequest nr;
1706         if (useDirect) {
1707             nr = getDirectNetworkRequest(clientId,
1708                     WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
1709                     provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null,
1710                     providePassphrase ? passphrase : null, 0);
1711         } else {
1712             nr = getSessionNetworkRequest(clientId, res.mSessionId,
1713                     provideMac ? res.mPeerHandle : null, providePmk ? pmk : null,
1714                     providePassphrase ? passphrase : null, true, 0);
1715         }
1716 
1717         Message reqNetworkMsg = Message.obtain();
1718         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
1719         reqNetworkMsg.obj = nr;
1720         reqNetworkMsg.arg1 = 0;
1721         res.mMessenger.send(reqNetworkMsg);
1722         mMockLooper.dispatchAll();
1723         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
1724 
1725         // (2) get request & respond (if legacy)
1726         mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
1727         mMockLooper.dispatchAll();
1728         inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true),
1729                 eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
1730                 eq(providePassphrase ? passphrase : null), eq(null), eq(useDirect), any());
1731         mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
1732         mMockLooper.dispatchAll();
1733 
1734         // (3) get confirmation OR timeout
1735         if (getConfirmation) {
1736             mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null);
1737             mMockLooper.dispatchAll();
1738             inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
1739             inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
1740             inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
1741             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
1742                     eq(useDirect), anyLong());
1743             inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
1744             WifiAwareNetworkInfo netInfo =
1745                     (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
1746                             .getTransportInfo();
1747             assertArrayEquals(MacAddress.fromBytes(
1748                     peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
1749                     netInfo.getPeerIpv6Addr().getAddress());
1750             assertEquals(0, netInfo.getPort());
1751             assertEquals(-1, netInfo.getTransportProtocol());
1752             assertEquals(1, mDut.mDataPathMgr.getNumOfNdps());
1753         } else {
1754             assertTrue(mAlarmManager.dispatch(
1755                     WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
1756             mMockLooper.dispatchAll();
1757             verifyRequestDeclaredUnfullfillable(nr);
1758             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
1759             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
1760             mMockLooper.dispatchAll();
1761             inOrderM.verify(mAwareMetricsMock).recordNdpStatus(
1762                     eq(NanStatusType.INTERNAL_FAILURE), eq(useDirect), anyLong());
1763         }
1764 
1765         // (4) end data-path (unless didn't get confirmation)
1766         if (getConfirmation) {
1767             Message endNetworkMsg = Message.obtain();
1768             endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
1769             endNetworkMsg.obj = nr;
1770             res.mMessenger.send(endNetworkMsg);
1771 
1772             agentCaptor.getValue().onNetworkUnwanted();
1773 
1774             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
1775             mDut.onDataPathEndNotification(ndpId);
1776             mMockLooper.dispatchAll();
1777 
1778             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
1779             inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString());
1780             inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
1781         }
1782         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
1783     }
1784 
getSessionNetworkRequest(int clientId, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId)1785     private NetworkRequest getSessionNetworkRequest(int clientId, int sessionId,
1786             PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId)
1787             throws Exception {
1788         return getSessionNetworkRequestMore(clientId, sessionId, peerHandle, pmk, passphrase,
1789                 doPublish, requestId, 0, -1);
1790     }
1791 
getSessionNetworkRequestMore(int clientId, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId, int port, int transportProtocol)1792     private NetworkRequest getSessionNetworkRequestMore(int clientId, int sessionId,
1793             PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId,
1794             int port, int transportProtocol)
1795             throws Exception {
1796         final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class);
1797         final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService);
1798         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1799         final PublishConfig publishConfig = new PublishConfig.Builder().build();
1800         final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1801 
1802         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
1803                 WifiAwareSession.class);
1804         ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
1805                 .forClass(IWifiAwareEventCallback.class);
1806         ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
1807                 .forClass(IWifiAwareDiscoverySessionCallback.class);
1808         ArgumentCaptor<DiscoverySession> discoverySession = ArgumentCaptor
1809                 .forClass(DiscoverySession.class);
1810 
1811         AttachCallback mockCallback = mock(AttachCallback.class);
1812         DiscoverySessionCallback mockSessionCallback = mock(
1813                 DiscoverySessionCallback.class);
1814 
1815         InOrder inOrderS = inOrder(mockAwareService, mockCallback, mockSessionCallback);
1816 
1817         mgr.attach(mMockLooperHandler, configRequest, mockCallback, null);
1818         inOrderS.verify(mockAwareService).connect(any(), any(), any(),
1819                 clientProxyCallback.capture(), eq(configRequest), eq(false));
1820         IWifiAwareEventCallback iwaec = clientProxyCallback.getValue();
1821         iwaec.onConnectSuccess(clientId);
1822         mMockLooper.dispatchAll();
1823         inOrderS.verify(mockCallback).onAttached(sessionCaptor.capture());
1824         if (doPublish) {
1825             sessionCaptor.getValue().publish(publishConfig, mockSessionCallback,
1826                     mMockLooperHandler);
1827             inOrderS.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig),
1828                     sessionProxyCallback.capture());
1829         } else {
1830             sessionCaptor.getValue().subscribe(subscribeConfig, mockSessionCallback,
1831                     mMockLooperHandler);
1832             inOrderS.verify(mockAwareService).subscribe(any(), any(), eq(clientId),
1833                     eq(subscribeConfig), sessionProxyCallback.capture());
1834         }
1835         sessionProxyCallback.getValue().onSessionStarted(sessionId);
1836         mMockLooper.dispatchAll();
1837         if (doPublish) {
1838             inOrderS.verify(mockSessionCallback).onPublishStarted(
1839                     (PublishDiscoverySession) discoverySession.capture());
1840         } else {
1841             inOrderS.verify(mockSessionCallback).onSubscribeStarted(
1842                     (SubscribeDiscoverySession) discoverySession.capture());
1843         }
1844 
1845         NetworkSpecifier ns;
1846         if (pmk == null && passphrase == null) {
1847             ns = createNetworkSpecifier(clientId,
1848                     doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
1849                             : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
1850                     peerHandle, null, null, port, transportProtocol);
1851         } else if (passphrase == null) {
1852             ns = createNetworkSpecifier(clientId,
1853                     doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
1854                             : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
1855                     peerHandle, pmk, null, port, transportProtocol);
1856         } else {
1857             ns = createNetworkSpecifier(clientId,
1858                     doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
1859                             : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
1860                     peerHandle, null, passphrase, port, transportProtocol);
1861         }
1862 
1863         NetworkCapabilities nc = new NetworkCapabilities();
1864         nc.clearAll();
1865         nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE);
1866         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability(
1867                 NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1868         nc.setNetworkSpecifier(ns);
1869         nc.setLinkUpstreamBandwidthKbps(1);
1870         nc.setLinkDownstreamBandwidthKbps(1);
1871         nc.setSignalStrength(1);
1872         nc.setRequestorUid(Process.myUid());
1873         nc.setRequestorPackageName(TEST_PACKAGE_NAME);
1874 
1875         return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST);
1876     }
1877 
getDirectNetworkRequest(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int requestId)1878     private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer,
1879             byte[] pmk, String passphrase, int requestId) throws Exception {
1880         return getDirectNetworkRequestMore(clientId, role, peer, pmk, passphrase, requestId, 0, -1);
1881     }
1882 
getDirectNetworkRequestMore(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int requestId, int port, int transportProtocol)1883     private NetworkRequest getDirectNetworkRequestMore(int clientId, int role, byte[] peer,
1884             byte[] pmk, String passphrase, int requestId, int port, int transportProtocol)
1885             throws Exception {
1886         final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class);
1887         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1888         final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService);
1889 
1890         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
1891                 WifiAwareSession.class);
1892         ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
1893                 .forClass(IWifiAwareEventCallback.class);
1894 
1895         AttachCallback mockCallback = mock(AttachCallback.class);
1896 
1897         mgr.attach(mMockLooperHandler, configRequest, mockCallback, null);
1898         verify(mockAwareService).connect(any(), any(), any(),
1899                 clientProxyCallback.capture(), eq(configRequest), eq(false));
1900         clientProxyCallback.getValue().onConnectSuccess(clientId);
1901         mMockLooper.dispatchAll();
1902         verify(mockCallback).onAttached(sessionCaptor.capture());
1903 
1904         NetworkSpecifier ns;
1905         if (pmk == null && passphrase == null) {
1906             ns = createNetworkSpecifier(clientId, role, peer, null, null, port, transportProtocol);
1907         } else if (passphrase == null) {
1908             ns = createNetworkSpecifier(clientId, role, peer, pmk, null, port, transportProtocol);
1909         } else {
1910             ns = createNetworkSpecifier(clientId, role, peer, null, passphrase, port,
1911                     transportProtocol);
1912         }
1913         NetworkCapabilities nc = new NetworkCapabilities();
1914         nc.clearAll();
1915         nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE);
1916         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
1917             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
1918             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
1919             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
1920         nc.setNetworkSpecifier(ns);
1921         nc.setLinkUpstreamBandwidthKbps(1);
1922         nc.setLinkDownstreamBandwidthKbps(1);
1923         nc.setSignalStrength(1);
1924         nc.setRequestorUid(Process.myUid());
1925         nc.setRequestorPackageName(TEST_PACKAGE_NAME);
1926 
1927         return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST);
1928     }
1929 
initDataPathEndPoint(boolean isFirstIteration, int clientId, byte pubSubId, int requestorId, byte[] peerDiscoveryMac, InOrder inOrder, InOrder inOrderM, boolean doPublish)1930     private DataPathEndPointInfo initDataPathEndPoint(boolean isFirstIteration, int clientId,
1931             byte pubSubId, int requestorId, byte[] peerDiscoveryMac, InOrder inOrder,
1932             InOrder inOrderM, boolean doPublish)
1933             throws Exception {
1934         final String someMsg = "some arbitrary message from peer";
1935         final PublishConfig publishConfig = new PublishConfig.Builder().build();
1936         final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1937 
1938         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1939         ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1940         ArgumentCaptor<Integer> peerIdCaptor = ArgumentCaptor.forClass(Integer.class);
1941 
1942         Messenger messenger = initOobDataPathEndPoint(isFirstIteration, 1, clientId, inOrder,
1943                 inOrderM);
1944 
1945         if (doPublish) {
1946             mDut.publish(clientId, publishConfig, mMockSessionCallback);
1947         } else {
1948             mDut.subscribe(clientId, subscribeConfig, mMockSessionCallback);
1949         }
1950         mMockLooper.dispatchAll();
1951         if (doPublish) {
1952             inOrder.verify(mMockNative).publish(transactionId.capture(), eq((byte) 0),
1953                     eq(publishConfig));
1954         } else {
1955             inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0),
1956                     eq(subscribeConfig));
1957         }
1958         mDut.onSessionConfigSuccessResponse(transactionId.getValue(), doPublish, pubSubId);
1959         mMockLooper.dispatchAll();
1960         inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture());
1961         inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(Process.myUid()), any());
1962         inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(Process.myUid(),
1963                 NanStatusType.SUCCESS, doPublish);
1964 
1965         mDut.onMessageReceivedNotification(pubSubId, requestorId, peerDiscoveryMac,
1966                 someMsg.getBytes());
1967         mMockLooper.dispatchAll();
1968         inOrder.verify(mMockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
1969                 eq(someMsg.getBytes()));
1970 
1971         return new DataPathEndPointInfo(sessionId.getValue(), peerIdCaptor.getValue(),
1972                 isFirstIteration ? messenger : null);
1973     }
1974 
initOobDataPathEndPoint(boolean startUpSequence, int maxNdiInterfaces, int clientId, InOrder inOrder, InOrder inOrderM)1975     private Messenger initOobDataPathEndPoint(boolean startUpSequence,
1976             int maxNdiInterfaces, int clientId, InOrder inOrder, InOrder inOrderM)
1977             throws Exception {
1978         final int pid = 2000;
1979         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1980 
1981         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1982         ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class);
1983         ArgumentCaptor<NetworkProvider> networkProviderCaptor =
1984                 ArgumentCaptor.forClass(NetworkProvider.class);
1985         ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class);
1986 
1987         Capabilities capabilities = new Capabilities();
1988         capabilities.maxNdiInterfaces = maxNdiInterfaces;
1989 
1990         if (startUpSequence) {
1991             // (0) start/registrations
1992             inOrder.verify(mMockCm).registerNetworkProvider(networkProviderCaptor.capture());
1993             collector.checkThat("factory name", "WIFI_AWARE_FACTORY",
1994                     equalTo(networkProviderCaptor.getValue().getName()));
1995 
1996             // (1) get capabilities
1997             mDut.queryCapabilities();
1998             mMockLooper.dispatchAll();
1999             inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2000             mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities);
2001             mMockLooper.dispatchAll();
2002 
2003             // (2) enable usage
2004             mDut.enableUsage();
2005             mMockLooper.dispatchAll();
2006             inOrderM.verify(mAwareMetricsMock).recordEnableUsage();
2007         }
2008 
2009         // (3) create client
2010         mDut.connect(clientId, Process.myUid(), pid, TEST_PACKAGE_NAME, TEST_FEATURE_ID,
2011                 mMockCallback, configRequest, false);
2012         mMockLooper.dispatchAll();
2013 
2014         if (startUpSequence) {
2015             inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
2016                     eq(configRequest), eq(false), eq(true), eq(true),
2017                     eq(false), eq(false), eq(false));
2018             mDut.onConfigSuccessResponse(transactionId.getValue());
2019             mMockLooper.dispatchAll();
2020         }
2021 
2022         inOrder.verify(mMockCallback).onConnectSuccess(clientId);
2023         inOrderM.verify(mAwareMetricsMock).recordAttachSession(eq(Process.myUid()), eq(false),
2024                 any());
2025 
2026         if (startUpSequence) {
2027             for (int i = 0; i < maxNdiInterfaces; ++i) {
2028                 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(),
2029                         strCaptor.capture());
2030                 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i,
2031                         equalTo(strCaptor.getValue()));
2032                 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
2033                 mMockLooper.dispatchAll();
2034             }
2035             Messenger messenger = networkProviderCaptor.getValue().getMessenger();
2036             return messenger;
2037         }
2038 
2039         return null;
2040     }
2041 
2042     /**
2043      * Copy of DiscoverySession.createNetworkSpecifier - but without any checks! Allows creating
2044      * network requests which may not be valid (e.g. for the API level).
2045      */
createNetworkSpecifier(int clientId, int role, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, int port, int transportProtocol)2046     public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId,
2047             PeerHandle peerHandle, byte[] pmk, String passphrase, int port, int transportProtocol) {
2048         return new WifiAwareNetworkSpecifier(
2049                 (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
2050                         : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
2051                 role,
2052                 clientId,
2053                 sessionId,
2054                 peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
2055                 null, // peerMac (not used in this method)
2056                 pmk,
2057                 passphrase,
2058                 port,
2059                 transportProtocol);
2060     }
2061 
2062     /**
2063      * Copy of WifiAwareSession.createNetworkSpecifier - but without any checks! Allows creating
2064      * network requests which may not be valid (e.g. for the API level).
2065      */
createNetworkSpecifier(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int port, int transportProtocol)2066     private NetworkSpecifier createNetworkSpecifier(int clientId, int role, byte[] peer, byte[] pmk,
2067             String passphrase, int port, int transportProtocol) {
2068         return new WifiAwareNetworkSpecifier(
2069                 (peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
2070                         : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
2071                 role,
2072                 clientId,
2073                 0, // 0 is an invalid session ID
2074                 0, // 0 is an invalid peer ID
2075                 peer,
2076                 pmk,
2077                 passphrase,
2078                 port,
2079                 transportProtocol);
2080     }
2081 
2082     private static class DataPathEndPointInfo {
2083         int mSessionId;
2084         PeerHandle mPeerHandle;
2085         Messenger mMessenger;
2086 
DataPathEndPointInfo(int sessionId, int peerId, Messenger messenger)2087         DataPathEndPointInfo(int sessionId, int peerId, Messenger messenger) {
2088             mSessionId = sessionId;
2089             mPeerHandle = new PeerHandle(peerId);
2090             mMessenger = messenger;
2091         }
2092     }
2093 
2094     /**
2095      * Verify that declareNetworkRequestUnfulfillable was called.
2096      */
verifyRequestDeclaredUnfullfillable(NetworkRequest request)2097     private void verifyRequestDeclaredUnfullfillable(NetworkRequest request) throws Exception {
2098         mMockLooper.dispatchAll();
2099         verify(mMockCm, atLeastOnce()).declareNetworkRequestUnfulfillable(any());
2100     }
2101 
2102     // copy of the method in WifiAwareDataPathStateManager - but without error checking (so we can
2103     // construct invalid TLVs for testing).
buildTlv(int port, int transportProtocol, boolean includeGarbageTlv)2104     private static byte[] buildTlv(int port, int transportProtocol, boolean includeGarbageTlv) {
2105         if (port == 0 && transportProtocol == -1) {
2106             return null;
2107         }
2108 
2109         TlvBufferUtils.TlvConstructor tlvc = new TlvBufferUtils.TlvConstructor(1, 2);
2110         tlvc.setByteOrder(ByteOrder.LITTLE_ENDIAN);
2111         tlvc.allocate(30); // safe size for now
2112 
2113         tlvc.putRawByteArray(WifiAwareDataPathStateManager.NetworkInformationData.WFA_OUI);
2114         tlvc.putRawByte((byte) WifiAwareDataPathStateManager.NetworkInformationData
2115                 .GENERIC_SERVICE_PROTOCOL_TYPE);
2116 
2117         if (port != 0) {
2118             tlvc.putShort(WifiAwareDataPathStateManager.NetworkInformationData.SUB_TYPE_PORT,
2119                     (short) port);
2120         }
2121         if (transportProtocol != -1) {
2122             tlvc.putByte(WifiAwareDataPathStateManager.NetworkInformationData
2123                     .SUB_TYPE_TRANSPORT_PROTOCOL, (byte) transportProtocol);
2124         }
2125         if (includeGarbageTlv) {
2126             tlvc.putShort(55, (short) -1298);
2127         }
2128 
2129         byte[] subTypes = tlvc.getArray();
2130 
2131         tlvc.allocate(30);
2132         tlvc.putByteArray(WifiAwareDataPathStateManager.NetworkInformationData.SERVICE_INFO_TYPE,
2133                 subTypes);
2134         if (includeGarbageTlv) {
2135             tlvc.putInt(78, 44);
2136         }
2137 
2138         return tlvc.getArray();
2139     }
2140 
2141     @Test
testAcceptRequestWhenAwareNotReadyWillReleaseRequest()2142     public void testAcceptRequestWhenAwareNotReadyWillReleaseRequest() throws Exception {
2143         final int clientId = 123;
2144         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
2145         ArgumentCaptor<NetworkProvider> networkProviderCaptor =
2146                 ArgumentCaptor.forClass(NetworkProvider.class);
2147         verify(mMockCm).registerNetworkProvider(networkProviderCaptor.capture());
2148         NetworkProvider awareProvider = networkProviderCaptor.getValue();
2149         collector.checkThat("factory name", "WIFI_AWARE_FACTORY",
2150                 equalTo(awareProvider.getName()));
2151         NetworkRequest networkRequest = getDirectNetworkRequest(clientId,
2152                 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null,
2153                 null, 1);
2154         // Aware usage is not enabled, should declare unfullfillable.
2155         awareProvider.onNetworkRequested(networkRequest, 0, awareProvider.getProviderId());
2156         verifyRequestDeclaredUnfullfillable(networkRequest);
2157         reset(mMockCm);
2158         // Aware usage is enabled but interface not ready, should declare unfullfillable.
2159         mDut.enableUsage();
2160         mMockLooper.dispatchAll();
2161         awareProvider.onNetworkRequested(networkRequest, 0, awareProvider.getProviderId());
2162         verifyRequestDeclaredUnfullfillable(networkRequest);
2163     }
testDataPathAcceptsAnyResponderWithMultipleInitiator(boolean providePmk, boolean providePassphrase, boolean failureOnFirst)2164     private void testDataPathAcceptsAnyResponderWithMultipleInitiator(boolean providePmk,
2165             boolean providePassphrase, boolean failureOnFirst)
2166             throws Exception {
2167         final int clientId = 123;
2168         final byte pubSubId = 60;
2169         final int requestorId = 1341234;
2170         final byte[] pmk = "01234567890123456789012345678901".getBytes();
2171         final String passphrase = "some passphrase";
2172         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
2173         final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
2174         int indexOfFailure = failureOnFirst ? 0 : 1;
2175         int ndpAttemptsCount = 4;
2176         int ndpId = 2;
2177         List<Integer> successNdpIds = new ArrayList<>();
2178 
2179 
2180         ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor =
2181                 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class);
2182         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2183         InOrder inOrder = inOrder(mMockNative, mMockCallback, mMockSessionCallback,
2184                 mMockNetdWrapper, mMockNetworkInterface, mMockCm);
2185         InOrder inOrderM = inOrder(mAwareMetricsMock);
2186 
2187         if (providePmk) {
2188             when(mPermissionsWrapperMock.getUidPermission(
2189                     eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn(
2190                     PackageManager.PERMISSION_GRANTED);
2191         }
2192 
2193         // (0) initialize
2194         DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
2195                 peerDiscoveryMac, inOrder, inOrderM, true);
2196 
2197         // (1) request network
2198         NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId,
2199                 null, providePmk ? pmk : null,
2200                 providePassphrase ? passphrase : null, true, 0);
2201 
2202         Message reqNetworkMsg = Message.obtain();
2203         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
2204         reqNetworkMsg.obj = nr;
2205         reqNetworkMsg.arg1 = 0;
2206         res.mMessenger.send(reqNetworkMsg);
2207         mMockLooper.dispatchAll();
2208         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(
2209                 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER);
2210         boolean firstSuccess = true;
2211 
2212         for (int i = 0; i < ndpAttemptsCount; i++) {
2213             // (2) get request & respond
2214             peerDataPathMac[5] += i;
2215             mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
2216             mMockLooper.dispatchAll();
2217             inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true),
2218                     eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
2219                     eq(providePassphrase ? passphrase : null), eq(null), eq(false), any());
2220             mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
2221             mMockLooper.dispatchAll();
2222 
2223             // (3) get confirmation OR timeout
2224             if (i != indexOfFailure) {
2225                 successNdpIds.add(ndpId);
2226                 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null);
2227                 mMockLooper.dispatchAll();
2228                 if (firstSuccess) {
2229                     inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
2230                     inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
2231                     inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
2232                     WifiAwareNetworkInfo netInfo =
2233                             (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities
2234                                     .getTransportInfo();
2235                     assertArrayEquals(MacAddress.fromBytes(
2236                             peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
2237                             netInfo.getPeerIpv6Addr().getAddress());
2238                     assertEquals(0, netInfo.getPort());
2239                     assertEquals(-1, netInfo.getTransportProtocol());
2240                     assertEquals(1, mDut.mDataPathMgr.getNumOfNdps());
2241                 }
2242                 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
2243                         eq(false), anyLong());
2244                 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
2245                 assertEquals(successNdpIds.size(), mDut.mDataPathMgr.getNumOfNdps());
2246 
2247                 firstSuccess = false;
2248             } else {
2249                 assertTrue(mAlarmManager.dispatch(
2250                         WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
2251                 mMockLooper.dispatchAll();
2252                 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
2253                 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(
2254                         eq(NanStatusType.INTERNAL_FAILURE), eq(false), anyLong());
2255                 mDut.onDataPathEndNotification(ndpId);
2256                 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
2257                 verify(mMockCm, never()).declareNetworkRequestUnfulfillable(any());
2258             }
2259             ndpId++;
2260         }
2261 
2262         // (4) one of the NDP is terminated by the other side
2263         int endNdpId = successNdpIds.remove(0);
2264         mDut.onDataPathEndNotification(endNdpId);
2265         mMockLooper.dispatchAll();
2266 
2267         inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
2268         assertEquals(successNdpIds.size(), mDut.mDataPathMgr.getNumOfNdps());
2269 
2270 
2271         // (5) end data-path (unless didn't get confirmation)
2272         Message endNetworkMsg = Message.obtain();
2273         endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
2274         endNetworkMsg.obj = nr;
2275         res.mMessenger.send(endNetworkMsg);
2276         agentCaptor.getValue().onNetworkUnwanted();
2277 
2278         for (int successNdpId : successNdpIds) {
2279             mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
2280             mDut.onDataPathEndNotification(successNdpId);
2281             mMockLooper.dispatchAll();
2282             inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(successNdpId));
2283             inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong());
2284         }
2285         inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString());
2286         verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper);
2287     }
2288 
2289     @Test
testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFirstRequest()2290     public void testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFirstRequest()
2291             throws Exception {
2292         testDataPathAcceptsAnyResponderWithMultipleInitiator(false, true, true);
2293     }
2294 
2295     @Test
testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFollowingRequest()2296     public void testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFollowingRequest()
2297             throws Exception {
2298         testDataPathAcceptsAnyResponderWithMultipleInitiator(false, true, false);
2299     }
2300 
2301     /**
2302      * Validate when multiple request present on a device, request from peer can match to the right
2303      * accepts any peer request when no peer specific request matches.
2304      */
2305     @Test
testAcceptsAnyRequestMatchesCorrectlyWhenMultipleRequestPresent()2306     public void testAcceptsAnyRequestMatchesCorrectlyWhenMultipleRequestPresent() throws Exception {
2307         final int clientId = 123;
2308         final byte pubId = 1;
2309         final byte subId = -128;
2310         final int requestorId = 1341234;
2311         final String passphrase = "SomeSecurePassword";
2312         final String passphrase1 = "SomeSecurePassword1";
2313         final int ndpId = 1;
2314         final int ndpId2 = 2;
2315         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
2316         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2317         ArgumentCaptor<String> interfaceName1 = ArgumentCaptor.forClass(String.class);
2318         ArgumentCaptor<String> interfaceName2 = ArgumentCaptor.forClass(String.class);
2319 
2320         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
2321         InOrder inOrderM = inOrder(mAwareMetricsMock);
2322 
2323         Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM);
2324 
2325         // (0) initialize Publish
2326         DataPathEndPointInfo pubRes = initDataPathEndPoint(false, clientId, pubId, requestorId,
2327                 peerDiscoveryMac, inOrder, inOrderM, true);
2328 
2329         // (1) request responder network
2330         NetworkRequest pubNr = getSessionNetworkRequest(clientId, pubRes.mSessionId, null,
2331                 null, passphrase, true, requestorId);
2332 
2333         Message reqNetworkMsg = Message.obtain();
2334         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
2335         reqNetworkMsg.obj = pubNr;
2336         reqNetworkMsg.arg1 = 0;
2337         messenger.send(reqNetworkMsg);
2338         mMockLooper.dispatchAll();
2339         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
2340 
2341         // (2) initialize Subscribe
2342         DataPathEndPointInfo subRes = initDataPathEndPoint(false, clientId, subId, requestorId,
2343                 peerDiscoveryMac, inOrder, inOrderM, false);
2344 
2345         // (3) request initiator network
2346         NetworkRequest subNr = getSessionNetworkRequest(clientId, subRes.mSessionId,
2347                 subRes.mPeerHandle, null, passphrase1, false, requestorId);
2348 
2349         Message subReqNetworkMsg = Message.obtain();
2350         subReqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
2351         subReqNetworkMsg.obj = subNr;
2352         subReqNetworkMsg.arg1 = 0;
2353         messenger.send(subReqNetworkMsg);
2354         mMockLooper.dispatchAll();
2355         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
2356 
2357         // (4) Initiator request succeed
2358         verify(mMockNative).initiateDataPath(transactionId.capture(), anyInt(), anyInt(), anyInt(),
2359                 any(), interfaceName1.capture(), any(), anyString(), anyBoolean(), any(), any());
2360         mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId);
2361 
2362         // (5) provide a request from peer
2363         mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac, ndpId2, null);
2364         mMockLooper.dispatchAll();
2365 
2366         // (6) make sure framework respond with the right accepts any peer request.
2367         verify(mMockNative).respondToDataPathRequest(anyShort(), eq(true), eq(ndpId2),
2368                 interfaceName2.capture(), eq(null), eq(passphrase), any(), anyBoolean(), any());
2369 
2370         assertNotEquals(interfaceName1.getValue(), interfaceName2.getValue());
2371     }
2372 
2373     /**
2374      * Validate when both peer specific and accepts any peer requests are on the device, framework
2375      * will response to the matched peer with peer specific request. Other peers with accepts any
2376      * request.
2377      */
2378     @Test
testPeerSpecificRequestMatchesCorrectlyWhenAcceptsAnyRequestExist()2379     public void testPeerSpecificRequestMatchesCorrectlyWhenAcceptsAnyRequestExist()
2380             throws Exception {
2381         final int clientId = 123;
2382         final byte pubId = 1;
2383         final int requestorId = 1341234;
2384         final String passphrase = "SomeSecurePassword";
2385         final String passphrase1 = "SomeSecurePassword1";
2386         final int ndpId = 1;
2387         final int ndpId2 = 2;
2388         final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
2389         final byte[] peerDiscoveryMac1 = HexEncoding.decode("000102030406".toCharArray(), false);
2390         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2391         ArgumentCaptor<String> interfaceName1 = ArgumentCaptor.forClass(String.class);
2392         ArgumentCaptor<String> interfaceName2 = ArgumentCaptor.forClass(String.class);
2393 
2394         InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
2395         InOrder inOrderM = inOrder(mAwareMetricsMock);
2396 
2397         Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM);
2398 
2399         // (0) initialize Publish
2400         DataPathEndPointInfo pubRes = initDataPathEndPoint(false, clientId, pubId, requestorId,
2401                 peerDiscoveryMac, inOrder, inOrderM, true);
2402 
2403         // (1) request accepts any responder network
2404         NetworkRequest pubNr = getSessionNetworkRequest(clientId, pubRes.mSessionId, null,
2405                 null, passphrase, true, requestorId);
2406 
2407         Message reqNetworkMsg = Message.obtain();
2408         reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
2409         reqNetworkMsg.obj = pubNr;
2410         reqNetworkMsg.arg1 = 0;
2411         messenger.send(reqNetworkMsg);
2412         mMockLooper.dispatchAll();
2413         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
2414 
2415         // (2) request peer specific responder network
2416         NetworkRequest subNr = getSessionNetworkRequest(clientId, pubRes.mSessionId,
2417                 pubRes.mPeerHandle, null, passphrase1, true, requestorId);
2418 
2419         Message subReqNetworkMsg = Message.obtain();
2420         subReqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK;
2421         subReqNetworkMsg.obj = subNr;
2422         subReqNetworkMsg.arg1 = 0;
2423         messenger.send(subReqNetworkMsg);
2424         mMockLooper.dispatchAll();
2425         inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
2426 
2427         // (3) provide a request from specified peer
2428         mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac, ndpId, null);
2429         mMockLooper.dispatchAll();
2430 
2431         // (4) make sure framework respond with the peer specific request.
2432         verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true), eq(ndpId),
2433                 interfaceName1.capture(), eq(null), eq(passphrase1), any(), anyBoolean(), any());
2434         mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
2435         mMockLooper.dispatchAll();
2436 
2437         // (5) provide a request from a not specified peer.
2438         mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac1, ndpId2, null);
2439         mMockLooper.dispatchAll();
2440 
2441         // (6) make sure framework respond with the right accepts any peer request.
2442         verify(mMockNative).respondToDataPathRequest(anyShort(), eq(true), eq(ndpId2),
2443                 interfaceName2.capture(), eq(null), eq(passphrase), any(), anyBoolean(), any());
2444 
2445         assertNotEquals(interfaceName1.getValue(), interfaceName2.getValue());
2446     }
2447 }
2448