WifiAwareStateManagerTest.java revision b5ff110bcdf4a178e712184c06ff7c8b200e125d
1956f54b391677d78379729dd14518edddf3c7660Etan Cohen/*
2956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Copyright (C) 2016 The Android Open Source Project
3956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
4956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5956f54b391677d78379729dd14518edddf3c7660Etan Cohen * you may not use this file except in compliance with the License.
6956f54b391677d78379729dd14518edddf3c7660Etan Cohen * You may obtain a copy of the License at
7956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
8956f54b391677d78379729dd14518edddf3c7660Etan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9956f54b391677d78379729dd14518edddf3c7660Etan Cohen *
10956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Unless required by applicable law or agreed to in writing, software
11956f54b391677d78379729dd14518edddf3c7660Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12956f54b391677d78379729dd14518edddf3c7660Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13956f54b391677d78379729dd14518edddf3c7660Etan Cohen * See the License for the specific language governing permissions and
14956f54b391677d78379729dd14518edddf3c7660Etan Cohen * limitations under the License.
15956f54b391677d78379729dd14518edddf3c7660Etan Cohen */
16956f54b391677d78379729dd14518edddf3c7660Etan Cohen
17956f54b391677d78379729dd14518edddf3c7660Etan Cohenpackage com.android.server.wifi.nan;
18956f54b391677d78379729dd14518edddf3c7660Etan Cohen
19956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.hamcrest.core.IsEqual.equalTo;
2012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohenimport static org.hamcrest.core.IsNull.notNullValue;
2122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenimport static org.hamcrest.core.IsNull.nullValue;
2222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenimport static org.junit.Assert.assertTrue;
231b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Matchers.any;
241b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Matchers.anyBoolean;
251b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Matchers.anyInt;
261b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Matchers.anyShort;
27956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Matchers.eq;
28956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.inOrder;
29956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.mock;
309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohenimport static org.mockito.Mockito.times;
31956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.verifyNoMoreInteractions;
321b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Mockito.when;
33956f54b391677d78379729dd14518edddf3c7660Etan Cohen
341b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.content.Context;
351b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.content.Intent;
367335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohenimport android.net.wifi.RttManager;
37956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.net.wifi.nan.ConfigRequest;
38676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohenimport android.net.wifi.nan.IWifiNanEventCallback;
39676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohenimport android.net.wifi.nan.IWifiNanSessionCallback;
408f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohenimport android.net.wifi.nan.PublishConfig;
418f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohenimport android.net.wifi.nan.SubscribeConfig;
429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohenimport android.net.wifi.nan.WifiNanEventCallback;
431b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.net.wifi.nan.WifiNanManager;
44676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohenimport android.net.wifi.nan.WifiNanSessionCallback;
451b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.os.UserHandle;
46956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.test.suitebuilder.annotation.SmallTest;
4722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenimport android.util.SparseArray;
48956f54b391677d78379729dd14518edddf3c7660Etan Cohen
494375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohenimport com.android.server.wifi.MockAlarmManager;
50956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport com.android.server.wifi.MockLooper;
51956f54b391677d78379729dd14518edddf3c7660Etan Cohen
52956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport libcore.util.HexEncoding;
53956f54b391677d78379729dd14518edddf3c7660Etan Cohen
54956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Before;
55956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Rule;
56956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Test;
57956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.rules.ErrorCollector;
58956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.ArgumentCaptor;
59956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.InOrder;
60956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.Mock;
61956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.MockitoAnnotations;
62956f54b391677d78379729dd14518edddf3c7660Etan Cohen
63956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport java.lang.reflect.Constructor;
64956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport java.lang.reflect.Field;
65956f54b391677d78379729dd14518edddf3c7660Etan Cohen
66956f54b391677d78379729dd14518edddf3c7660Etan Cohen/**
67956f54b391677d78379729dd14518edddf3c7660Etan Cohen * Unit test harness for WifiNanStateManager.
68956f54b391677d78379729dd14518edddf3c7660Etan Cohen */
69956f54b391677d78379729dd14518edddf3c7660Etan Cohen@SmallTest
70956f54b391677d78379729dd14518edddf3c7660Etan Cohenpublic class WifiNanStateManagerTest {
71956f54b391677d78379729dd14518edddf3c7660Etan Cohen    private MockLooper mMockLooper;
72956f54b391677d78379729dd14518edddf3c7660Etan Cohen    private WifiNanStateManager mDut;
73956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Mock private WifiNanNative mMockNative;
741b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Mock private Context mMockContext;
757335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    @Mock private WifiNanRttStateManager mMockNanRttStateManager;
764375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    MockAlarmManager mAlarmManager;
77956f54b391677d78379729dd14518edddf3c7660Etan Cohen
78956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Rule
79956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public ErrorCollector collector = new ErrorCollector();
80956f54b391677d78379729dd14518edddf3c7660Etan Cohen
819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Pre-test configuration. Initialize and install mocks.
839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
84956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Before
85956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void setUp() throws Exception {
86956f54b391677d78379729dd14518edddf3c7660Etan Cohen        MockitoAnnotations.initMocks(this);
87956f54b391677d78379729dd14518edddf3c7660Etan Cohen
884375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mAlarmManager = new MockAlarmManager();
894375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        when(mMockContext.getSystemService(Context.ALARM_SERVICE))
904375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen                .thenReturn(mAlarmManager.getAlarmManager());
914375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
92956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper = new MockLooper();
93956f54b391677d78379729dd14518edddf3c7660Etan Cohen
947335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut = installNewNanStateManagerAndResetState(mMockNanRttStateManager);
951b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.start(mMockContext, mMockLooper.getLooper());
961b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
971b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.enableAndConfigure(anyShort(), any(ConfigRequest.class), anyBoolean()))
981b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                .thenReturn(true);
991b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.disable(anyShort())).thenReturn(true);
1001b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.publish(anyShort(), anyInt(), any(PublishConfig.class))).thenReturn(true);
1011b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.subscribe(anyShort(), anyInt(), any(SubscribeConfig.class)))
1021b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                .thenReturn(true);
1031b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(byte[].class),
1041b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                any(byte[].class), anyInt())).thenReturn(true);
1051b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.stopPublish(anyShort(), anyInt())).thenReturn(true);
1061b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.stopSubscribe(anyShort(), anyInt())).thenReturn(true);
107956f54b391677d78379729dd14518edddf3c7660Etan Cohen
108956f54b391677d78379729dd14518edddf3c7660Etan Cohen        installMockWifiNanNative(mMockNative);
109956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
110956f54b391677d78379729dd14518edddf3c7660Etan Cohen
11112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
1121b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     * Validate that APIs aren't functional when usage is disabled.
1131b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
1141b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Test
1151b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    public void testDisableUsageDisablesApis() throws Exception {
1161b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final int clientId = 12314;
1171b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1181b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1191b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1201b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
1211b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
122b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
123b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
124b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
1251b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (1) check initial state
1261b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateCorrectNanStatusChangeBroadcast(inOrder, true);
127b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1281b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
1291b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1301b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (2) disable usage and validate state
1311b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
1321b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1331b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
1341b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).disable((short) 0);
1351b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateCorrectNanStatusChangeBroadcast(inOrder, false);
1361b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
137f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen        // (3) try connecting and validate that get nothing (app should be aware of non-availability
138f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen        // through state change broadcast and/or query API)
1391b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
1401b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1411b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1421bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
1431b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
1441b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1451b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
146f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * Validate that when API usage is disabled while in the middle of a connection that internal
147f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * state is cleaned-up, and that all subsequent operations are NOP. Then enable usage again and
148f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * validate that operates correctly.
1491b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
1501b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Test
1511b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    public void testDisableUsageFlow() throws Exception {
1521b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final int clientId = 12341;
1531b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1541b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1551b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1561b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1571b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
1581b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
159b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
160b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
161b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
1621b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (1) check initial state
1631b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateCorrectNanStatusChangeBroadcast(inOrder, true);
164b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1651b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
1661b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1671b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (2) connect (successfully)
1681b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
1691b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1701b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1711b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                eq(true));
1721b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1731b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1741b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
1751b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1761b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (3) disable usage & verify callbacks
1771b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
1781b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1791b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
1801b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).disable((short) 0);
1811b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateCorrectNanStatusChangeBroadcast(inOrder, false);
1821b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateInternalClientInfoCleanedUp(clientId);
1831b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1841b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (4) try connecting again and validate that just get an onNanDown
1851b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
1861b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1871b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1881b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (5) disable usage again and validate that not much happens
1891b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
1901b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1911b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
1921b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1931b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (6) enable usage
1941b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.enableUsage();
1951b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
1961b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
1971b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateCorrectNanStatusChangeBroadcast(inOrder, true);
1981b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
199b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        // note: this is called a second time (which it shouldn't if capabilties were obtained
200b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        // at first) because this test case does not provide a capabilities response.
201b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
202b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
2031b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (7) connect (should be successful)
2041b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
2051b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2061b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2071b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                eq(true));
2081b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
2091b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2101b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
2111b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
212ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
2131b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
2141b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2151b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
2169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validates that all events are delivered with correct arguments. Validates
2179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * that IdentityChanged not delivered if configuration disables delivery.
21812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
219956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
2209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public void testNanEventsDelivery() throws Exception {
2219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId1 = 1005;
2229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId2 = 1007;
223c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int clusterLow = 5;
224c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int clusterHigh = 100;
225c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int masterPref = 111;
2269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reason = WifiNanEventCallback.REASON_OTHER;
227956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
228956f54b391677d78379729dd14518edddf3c7660Etan Cohen
229c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow)
230c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
2319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setEnableIdentityChangeCallback(false).build();
23222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
233c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow)
234c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
2359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setEnableIdentityChangeCallback(true).build();
23622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback1 = mock(IWifiNanEventCallback.class);
2389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback2 = mock(IWifiNanEventCallback.class);
2399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
2409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
241956f54b391677d78379729dd14518edddf3c7660Etan Cohen
242b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
243b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
244b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
245b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
2469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect 1st and 2nd clients
2479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId1, mockCallback1, configRequest1);
2489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId2, mockCallback2, configRequest2);
2499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
2519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest1), eq(true));
2529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        short transactionId = transactionIdCapture.getValue();
2539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId);
25422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
2559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback1).onConnectSuccess();
25622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) finish connection of 2nd client
2589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
2599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest2), eq(false));
2609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        transactionId = transactionIdCapture.getValue();
2619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId);
26222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) deliver NAN events
2649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onClusterChangeNotification(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, someMac);
2659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onInterfaceAddressChangeNotification(someMac);
2669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onNanDownNotification(reason);
26722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
26822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback2).onConnectSuccess();
2709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback2, times(2)).onIdentityChanged();
271956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId1);
2739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId2);
27422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
275ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
276956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
277956f54b391677d78379729dd14518edddf3c7660Etan Cohen
27812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
2794375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * Validate that when the HAL doesn't respond we get a TIMEOUT (which
2804375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * results in a failure response) at which point we can process additional
2814375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * commands. Steps: (1) connect, (2) publish - timeout, (3) publish +
2824375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * success.
2834375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     */
2844375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    @Test
2854375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    public void testHalNoResponseTimeout() throws Exception {
2864375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final int clientId = 12341;
2874375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
2884375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final PublishConfig publishConfig = new PublishConfig.Builder().build();
2894375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
2904375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
2914375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
2924375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2934375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
2944375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
295b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
296b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
297b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
298b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
2994375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (1) connect (successfully)
3004375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
3014375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3024375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
3034375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen                eq(true));
3044375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
3054375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3064375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
3074375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
3084375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (2) publish + timeout
3094375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
3104375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3114375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).publish(anyShort(), eq(0), eq(publishConfig));
3124375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        assertTrue(mAlarmManager.dispatch(WifiNanStateManager.HAL_COMMAND_TIMEOUT_TAG));
3134375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3144375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mockSessionCallback)
3154375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
3164375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        validateInternalNoSessions(clientId);
3174375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
3184375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (3) publish + success
3194375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
3204375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3214375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
3224375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, 9999);
3234375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
3244375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
3254375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
326ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
3274375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    }
3284375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
3294375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    /**
3309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validates publish flow: (1) initial publish (2) fail. Expected: get a
3319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * failure callback.
33212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
333956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
33412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishFail() throws Exception {
335c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
3369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reasonFail = WifiNanSessionCallback.REASON_NO_RESOURCES;
337956f54b391677d78379729dd14518edddf3c7660Etan Cohen
3389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
33912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
340956f54b391677d78379729dd14518edddf3c7660Etan Cohen
3419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
3429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
343956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
3449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
345956f54b391677d78379729dd14518edddf3c7660Etan Cohen
346b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
347b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
348b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
349b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
3509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
3519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
3529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
3539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
3549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest), eq(true));
3559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
3569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
3579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
358956f54b391677d78379729dd14518edddf3c7660Etan Cohen
35912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
3609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
361956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
3628f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
363956f54b391677d78379729dd14518edddf3c7660Etan Cohen
36412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) publish failure
3659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
366956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
3679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
3689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalNoSessions(clientId);
369956f54b391677d78379729dd14518edddf3c7660Etan Cohen
3709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
37112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
37212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
37312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
37412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validates the publish flow: (1) initial publish (2) success (3)
37512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
37612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (6) update session attempt. Expected: session ID callback + session
3779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * cleaned-up.
37812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
37912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
38012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishSuccessTerminated() throws Exception {
38112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
38212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int reasonTerminate = WifiNanSessionCallback.TERMINATE_REASON_DONE;
38312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
38412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
3859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
38612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
38712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
3889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
3899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
39012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
39112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
3929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
39312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
394b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
395b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
396b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
397b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
3989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
3999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
4009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
4029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest), eq(true));
4039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
4049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
40612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
40712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
4089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
409956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
4108f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
411956f54b391677d78379729dd14518edddf3c7660Etan Cohen
41212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) publish success
4139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
41422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
4159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
41612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
41712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) publish termination (from firmware - not app!)
4189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(publishId, reasonTerminate, true);
4199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
4219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
42212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) app update session (race condition: app didn't get termination
42312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // yet)
42412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
4259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
42712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) app terminates session
42812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.terminateSession(clientId, sessionId.getValue());
4299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
43112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) app updates session (app already knows that terminated - will get
43212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // a local FAIL).
43312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
434956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
435956f54b391677d78379729dd14518edddf3c7660Etan Cohen
43612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
43712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
4389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
43912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
44012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
44112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
44212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate the publish flow: (1) initial publish + (2) success + (3) update
44312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * + (4) update fails + (5) update + (6). Expected: session is still alive
44412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * after update failure so second update succeeds (no callbacks).
44512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
44612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
44712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishUpdateFail() throws Exception {
44812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
44912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
4509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reasonFail = WifiNanSessionCallback.REASON_INVALID_ARGS;
45112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
4529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
45312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
454956f54b391677d78379729dd14518edddf3c7660Etan Cohen
4559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
4569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
45712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
45812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
4599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
46012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
461b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
462b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
463b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
464b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
4659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
4669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
4679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
4699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
4709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
4719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
47312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
47412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
4759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
476956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
4778f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
478956f54b391677d78379729dd14518edddf3c7660Etan Cohen
47912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) publish success
4809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
481956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
4829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
48312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
48412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) update publish
48512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
48612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
48712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
4888f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                eq(publishConfig));
48912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
49012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) update fails
4919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
4929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
49412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
49512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) another update publish
49612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
49712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
49812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
49912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                eq(publishConfig));
50012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
50112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) update succeeds
5029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
50312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
5049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
50512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
506ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
50712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
50812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
50912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
51012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate race condition: publish pending but session terminated (due to
51112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * disconnect - can't terminate such a session directly from app). Need to
51212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * make sure that once publish succeeds (failure isn't a problem) the
51312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * session is immediately terminated since no-one is listening for it.
51412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
51512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
51612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testDisconnectWhilePublishPending() throws Exception {
51712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
51812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
51912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
52112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
52212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
5249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
52512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
5269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
52712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
528b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
529b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
530b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
531b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
5329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
5339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
5349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
5369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
5379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
53812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
5399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
54012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) initial publish
5429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
5439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
54412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
54512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) disconnect (but doesn't get executed until get response for
5479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // publish command)
5489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
54912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
55012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) publish success
5529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
5539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
554ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
55512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).stopPublish(transactionId.capture(), eq(publishId));
5569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
5579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
5589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId);
5599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
560ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
561956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
562956f54b391677d78379729dd14518edddf3c7660Etan Cohen
56312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
5649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validates subscribe flow: (1) initial subscribe (2) fail. Expected: get a
5659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * failure callback.
56612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
567956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
56812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeFail() throws Exception {
569c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
5709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reasonFail = WifiNanSessionCallback.REASON_NO_RESOURCES;
571956f54b391677d78379729dd14518edddf3c7660Etan Cohen
5729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
57312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
574956f54b391677d78379729dd14518edddf3c7660Etan Cohen
5759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
5769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
577956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
5789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
579956f54b391677d78379729dd14518edddf3c7660Etan Cohen
580b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
581b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
582b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
583b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
5849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
5859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
5869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
5889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
5899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
5909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
592956f54b391677d78379729dd14518edddf3c7660Etan Cohen
59312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
5949864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
595956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
5968f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
597956f54b391677d78379729dd14518edddf3c7660Etan Cohen
59812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe failure
5999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
600956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
6019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
6029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalNoSessions(clientId);
603956f54b391677d78379729dd14518edddf3c7660Etan Cohen
6049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
60512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
60612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
60712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
60812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validates the subscribe flow: (1) initial subscribe (2) success (3)
60912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
61012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (6) update session attempt. Expected: session ID callback + session
6119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * cleaned-up
61212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
61312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
61412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeSuccessTerminated() throws Exception {
61512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
61612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int reasonTerminate = WifiNanSessionCallback.TERMINATE_REASON_DONE;
61712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
61812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
62012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
62112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
6239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
62412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
62512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
6269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
62712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
628b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
629b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
630b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
631b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
6329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
6339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
6349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
6369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
6379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
6389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
64012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
64112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
6429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
643956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
6448f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
645956f54b391677d78379729dd14518edddf3c7660Etan Cohen
64612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe success
6479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
648956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
6499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
65012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
65112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) subscribe termination (from firmware - not app!)
6529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(subscribeId, reasonTerminate, false);
6539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
6559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
65612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) app update session (race condition: app didn't get termination
65712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // yet)
65812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
6599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
66112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) app terminates session
66212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.terminateSession(clientId, sessionId.getValue());
66322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
66422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
6659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (6) app updates session
6669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
6679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
66812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
66912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
67012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
67212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
67312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
67412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
67512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate the subscribe flow: (1) initial subscribe + (2) success + (3)
67612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * update + (4) update fails + (5) update + (6). Expected: session is still
67712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * alive after update failure so second update succeeds (no callbacks).
67812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
67912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
68012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeUpdateFail() throws Exception {
68112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
68212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
6839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reasonFail = WifiNanSessionCallback.REASON_INVALID_ARGS;
68412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
68612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
68712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
6899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
69012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
69112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
6929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
69312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
694b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
695b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
696b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
697b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
6989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
6999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
7009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
7029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
7039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
7049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
706956f54b391677d78379729dd14518edddf3c7660Etan Cohen
70712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
7089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
709956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
7108f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
711956f54b391677d78379729dd14518edddf3c7660Etan Cohen
71212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe success
7139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
714956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
7159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
71612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
71712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) update subscribe
71812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
71912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
72012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
7218f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                eq(subscribeConfig));
72212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
72312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) update fails
7249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
7259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
72712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
72812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) another update subscribe
72912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
73012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
73112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
73212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                eq(subscribeConfig));
73312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
73412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) update succeeds
7359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
73612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
7379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
73812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
739ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
740956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
741956f54b391677d78379729dd14518edddf3c7660Etan Cohen
74212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
74312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate race condition: subscribe pending but session terminated (due to
74412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * disconnect - can't terminate such a session directly from app). Need to
74512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * make sure that once subscribe succeeds (failure isn't a problem) the
74612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * session is immediately terminated since no-one is listening for it.
74712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
74812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
74912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testDisconnectWhileSubscribePending() throws Exception {
75012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
75112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
75212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
75412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
75512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
7579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
75812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
7599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
76012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
761b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
762b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
763b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
764b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
7659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
7669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
7679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
7699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
7709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
77112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
7729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
77312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7749864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) initial subscribe
7759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
7769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
77712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
77812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) disconnect (but doesn't get executed until get response for
7809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // subscribe command)
7819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
7829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
78312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) subscribe success
7859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
78612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
787ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
7889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).stopSubscribe((short) 0, subscribeId);
7899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
79012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId);
7929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
793ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
79412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
79512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
79612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
7971bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     * Validate (1) subscribe (success), (2) match (i.e. discovery), (3) message reception, (4)
7981bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     * message queuing failed, (5) message transmission failed (after ok queuing), (6) message
7991bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     * transmission success.
80012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
801956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
802956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void testMatchAndMessages() throws Exception {
803c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
804956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String serviceName = "some-service-name";
805956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String ssi = "some much longer and more arbitrary data";
806956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int subscribeCount = 7;
8079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reasonFail = WifiNanSessionCallback.REASON_TX_FAIL;
808956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int subscribeId = 15;
809956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int requestorId = 22;
810956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
811956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerSsi = "some peer ssi data";
812956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
813956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerMsg = "some message from peer";
8142e09c384f5ce86061b115f20fe3ca75a175d87f0Etan Cohen        final int messageId = 6948;
8151bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int messageId2 = 6949;
816956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
8188f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
8198f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setServiceSpecificInfo(ssi)
8208f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setSubscribeType(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE)
82122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setSubscribeCount(subscribeCount).build();
822956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
8249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
825956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
82612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
8279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
828956f54b391677d78379729dd14518edddf3c7660Etan Cohen
829b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
830b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
831b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
832b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
8339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
8349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
835956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
8379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest), eq(true));
8389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
8399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
841956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) subscribe
8439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
8449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8458f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
8469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
8479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
849956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) match
8519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
8529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
853956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
8559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
856956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message Rx
8589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(subscribeId, requestorId, peerMac, peerMsg.getBytes(),
8599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                peerMsg.length());
8609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(requestorId, peerMsg.getBytes(),
862956f54b391677d78379729dd14518edddf3c7660Etan Cohen                peerMsg.length());
863956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8641bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (4) message Tx queuing fail
86512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), ssi.length(),
8661da4332949ad1053078053097bfc59a72653f477Etan Cohen                messageId, 0);
867956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
868956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
869956f54b391677d78379729dd14518edddf3c7660Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
8701bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedFailResponse(transactionId.getValue(), reasonFail);
871956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId, reasonFail);
873956f54b391677d78379729dd14518edddf3c7660Etan Cohen
8741bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (5) message Tx successful queuing
87512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), ssi.length(),
8761da4332949ad1053078053097bfc59a72653f477Etan Cohen                messageId, 0);
877956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
878956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
879956f54b391677d78379729dd14518edddf3c7660Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
8801bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        short tid1 = transactionId.getValue();
8811bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid1);
882956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8831bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
8841bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (6) message Tx successful queuing
8851bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), ssi.length(),
8861da4332949ad1053078053097bfc59a72653f477Etan Cohen                messageId2, 0);
8871bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
8881bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
8891bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
8901bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        short tid2 = transactionId.getValue();
8911bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid2);
8921bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
8931bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
8941bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (5) and (6) final Tx results (on-air results)
8951bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendFailNotification(tid1, reasonFail);
8961bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(tid2);
8971bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
8981bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId, reasonFail);
8991bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId2);
900956f54b391677d78379729dd14518edddf3c7660Etan Cohen
901ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
902956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
903956f54b391677d78379729dd14518edddf3c7660Etan Cohen
90422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
90522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: in a single publish session interact with multiple peers
90622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * (different MAC addresses).
90722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
90822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
90922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testMultipleMessageSources() throws Exception {
910c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 300;
91122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 7;
91222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 7;
91322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 0;
91422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
91522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 88;
91622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId1 = 568;
91722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId2 = 873;
91822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMac1 = HexEncoding.decode("000102030405".toCharArray(), false);
91922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMac2 = HexEncoding.decode("060708090A0B".toCharArray(), false);
92022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer1 = "hey from 000102...";
92122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer2 = "hey from 0607...";
92222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer1 = "hey there 000102...";
92322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer2 = "hey there 0506...";
92422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId1 = 546;
92522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId2 = 9654;
9269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int reason = WifiNanSessionCallback.REASON_OTHER;
92722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
92822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
92922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
93022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
9318f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
9328f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
93322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
93422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
93512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
936676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
937676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
938676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
939676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
940b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
941b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
942b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
943b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
9449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
9459864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
94622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
9479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
9489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
9499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
9509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
95222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
9539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
9549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
9559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9568f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
9579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
95812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
95912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
96012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
9619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message received from peers 1 & 2
9629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(publishId, peerId1, peerMac1, msgFromPeer1.getBytes(),
96322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer1.length());
9649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(publishId, peerId2, peerMac2, msgFromPeer2.getBytes(),
96522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer2.length());
96622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
967676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId1, msgFromPeer1.getBytes(),
96822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer1.length());
969676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId2, msgFromPeer2.getBytes(),
97022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer2.length());
9719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
9729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) sending messages back to same peers: one Tx fails, other succeeds
9739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId2, msgToPeer2.getBytes(),
9741da4332949ad1053078053097bfc59a72653f477Etan Cohen                msgToPeer2.length(), msgToPeerId2, 0);
9759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
97622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId2),
97722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                eq(peerMac2), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()));
9789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        short transactionIdVal = transactionId.getValue();
9791bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
9801bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionIdVal);
9819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
9829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId1, msgToPeer1.getBytes(),
9831da4332949ad1053078053097bfc59a72653f477Etan Cohen                msgToPeer1.length(), msgToPeerId1, 0);
9849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
98622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId1),
98722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                eq(peerMac1), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()));
9889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        transactionIdVal = transactionId.getValue();
9891bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
9901bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendFailNotification(transactionIdVal, reason);
99122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
992676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(msgToPeerId1, reason);
9939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
994ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
99522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
99622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
99722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
99822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: interact with a peer which changed its identity (MAC address)
99922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * but which keeps its requestor instance ID. Should be transparent.
100022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
100122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
100222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testMessageWhilePeerChangesIdentity() throws Exception {
1003c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 300;
100422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 7;
100522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 7;
100622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 0;
100722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
100822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 88;
100922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId = 568;
101022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMacOrig = HexEncoding.decode("000102030405".toCharArray(), false);
101122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMacLater = HexEncoding.decode("060708090A0B".toCharArray(), false);
101222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer1 = "hey from 000102...";
101322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer2 = "hey from 0607...";
101422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer1 = "hey there 000102...";
101522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer2 = "hey there 0506...";
101622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId1 = 546;
101722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId2 = 9654;
101822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
101922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
102022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
10218f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
10228f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
102322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
102422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
102512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1026676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1027676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
1028676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1029676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
1030b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1031b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1032b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1033b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
10349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
10359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
103622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
10379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
10389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
10399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
10409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
10419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
104222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
10439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
10449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
10459864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
10468f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
10479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
104822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
104912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
105012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
10519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message received & responded to
10529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(publishId, peerId, peerMacOrig, msgFromPeer1.getBytes(),
105312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                msgFromPeer1.length());
105412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer1.getBytes(),
10551da4332949ad1053078053097bfc59a72653f477Etan Cohen                msgToPeer1.length(), msgToPeerId1, 0);
105612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
1057676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer1.getBytes(),
105822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer1.length());
105922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
106022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                eq(peerMacOrig), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()));
10611bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
10621bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
10639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
10649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId1);
106522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
10669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) message received with same peer ID but different MAC
10679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(publishId, peerId, peerMacLater, msgFromPeer2.getBytes(),
106822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer2.length());
106912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer2.getBytes(),
10701da4332949ad1053078053097bfc59a72653f477Etan Cohen                msgToPeer2.length(), msgToPeerId2, 0);
107122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
1072676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer2.getBytes(),
107322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                msgFromPeer2.length());
107422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
107522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                eq(peerMacLater), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()));
10761bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
10771bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
107822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
1079676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
108022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1081ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
108222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
108322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
10849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
10859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validate that get failure (with correct code) when trying to send a
10869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * message to an invalid peer ID.
10879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
1088956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
1089cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    public void testSendMessageToInvalidPeerId() throws Exception {
1090cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int clientId = 1005;
1091cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String ssi = "some much longer and more arbitrary data";
1092cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int subscribeId = 15;
1093cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int requestorId = 22;
1094cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
1095cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String peerSsi = "some peer ssi data";
1096cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String peerMatchFilter = "filter binary array represented as string";
1097cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int messageId = 6948;
1098cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
10999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
1100cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1101cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
11029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
11039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
1104cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
110512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
11069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
1107cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
1108b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1109b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1110b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1111b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
11129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
11139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
11149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
11159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
11169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
11179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1118cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
11199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
1120cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
11219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) subscribe & match
11229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
11239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1124cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
11259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
11269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
11279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
1128cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
11299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
11309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
11319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
1132cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
11339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) send message to invalid peer ID
113412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId + 5, ssi.getBytes(),
11351da4332949ad1053078053097bfc59a72653f477Etan Cohen                ssi.length(), messageId, 0);
1136cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
11379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
11389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                WifiNanSessionCallback.REASON_NO_MATCH_SESSION);
1139cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
1140ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
1141cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    }
1142cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
11439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
11441bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     * Validate that on send message timeout correct callback is dispatched and that a later
11451bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     * firmware notification is ignored.
11461bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     */
11471bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    @Test
11481bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    public void testSendMessageTimeout() throws Exception {
11491bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int clientId = 1005;
11501bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String ssi = "some much longer and more arbitrary data";
11511bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int subscribeId = 15;
11521bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int requestorId = 22;
11531bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
11541bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String peerSsi = "some peer ssi data";
11551bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
11561bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int messageId = 6948;
11571bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
11581bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
11591bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
11601bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
11611bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
11621bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
11631bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
11641bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
11651bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
11661bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1167b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1168b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1169b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1170b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
11711bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (1) connect
11721bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
11731bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11741bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
11751bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                eq(true));
11761bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
11771bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11781bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
11791bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
11801bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (2) subscribe & match
11811bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
11821bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11831bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
11841bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
11851bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
11861bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
11871bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11881bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
11891bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
11901bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
11911bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
11921bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (3) send message and enqueue successfully
11931bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
11941da4332949ad1053078053097bfc59a72653f477Etan Cohen                ssi.length(), messageId, 0);
11951bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11961bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
11971bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
11981bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
11991bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
12001bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
12011bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (4) message send timeout
12021bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        assertTrue(mAlarmManager.dispatch(WifiNanStateManager.HAL_SEND_MESSAGE_TIMEOUT_TAG));
12031bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
12041bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
12051bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen                WifiNanSessionCallback.REASON_TX_FAIL);
12061bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
12071bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (5) firmware response (unlikely - but good to check)
12081bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
12091bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
12101bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
12111bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
12121da4332949ad1053078053097bfc59a72653f477Etan Cohen    }
12131da4332949ad1053078053097bfc59a72653f477Etan Cohen
12141da4332949ad1053078053097bfc59a72653f477Etan Cohen    /**
12151da4332949ad1053078053097bfc59a72653f477Etan Cohen     * Validate that when sending a message with a retry count the message is retried the specified
12161da4332949ad1053078053097bfc59a72653f477Etan Cohen     * number of times. Scenario ending with success.
12171da4332949ad1053078053097bfc59a72653f477Etan Cohen     */
12181da4332949ad1053078053097bfc59a72653f477Etan Cohen    @Test
12191da4332949ad1053078053097bfc59a72653f477Etan Cohen    public void testSendMessageRetransmitSuccess() throws Exception {
12201da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int clientId = 1005;
12211da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String ssi = "some much longer and more arbitrary data";
12221da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int subscribeId = 15;
12231da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int requestorId = 22;
12241da4332949ad1053078053097bfc59a72653f477Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
12251da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerSsi = "some peer ssi data";
12261da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
12271da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int messageId = 6948;
12281da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int retryCount = 3;
12291da4332949ad1053078053097bfc59a72653f477Etan Cohen
12301da4332949ad1053078053097bfc59a72653f477Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
12311da4332949ad1053078053097bfc59a72653f477Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
12321da4332949ad1053078053097bfc59a72653f477Etan Cohen
12331da4332949ad1053078053097bfc59a72653f477Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
12341da4332949ad1053078053097bfc59a72653f477Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
12351da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
12361da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
12371da4332949ad1053078053097bfc59a72653f477Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
12381da4332949ad1053078053097bfc59a72653f477Etan Cohen
1239b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1240b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1241b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1242b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
12431da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (1) connect
12441da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
12451da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12461da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
12471da4332949ad1053078053097bfc59a72653f477Etan Cohen                eq(true));
12481da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
12491da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12501da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
12511da4332949ad1053078053097bfc59a72653f477Etan Cohen
12521da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (2) subscribe & match
12531da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
12541da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12551da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
12561da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
12571da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
12581da4332949ad1053078053097bfc59a72653f477Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
12591da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12601da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
12611da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
12621da4332949ad1053078053097bfc59a72653f477Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
12631da4332949ad1053078053097bfc59a72653f477Etan Cohen
12641da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (3) send message and enqueue successfully
12651da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
12661da4332949ad1053078053097bfc59a72653f477Etan Cohen                ssi.length(), messageId, retryCount);
12671da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12681da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
12691da4332949ad1053078053097bfc59a72653f477Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
12701da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
12711da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12721da4332949ad1053078053097bfc59a72653f477Etan Cohen
12731da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (4) loop and fail until reach retryCount
12741da4332949ad1053078053097bfc59a72653f477Etan Cohen        for (int i = 0; i < retryCount; ++i) {
12751da4332949ad1053078053097bfc59a72653f477Etan Cohen            mDut.onMessageSendFailNotification(transactionId.getValue(),
12761da4332949ad1053078053097bfc59a72653f477Etan Cohen                    WifiNanSessionCallback.REASON_TX_FAIL);
12771da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
12781da4332949ad1053078053097bfc59a72653f477Etan Cohen            inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
12791da4332949ad1053078053097bfc59a72653f477Etan Cohen                    eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
12801da4332949ad1053078053097bfc59a72653f477Etan Cohen            mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
12811da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
12821da4332949ad1053078053097bfc59a72653f477Etan Cohen        }
12831da4332949ad1053078053097bfc59a72653f477Etan Cohen
12841da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (5) succeed on last retry
12851da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
12861da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
12871da4332949ad1053078053097bfc59a72653f477Etan Cohen
12881da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
12891da4332949ad1053078053097bfc59a72653f477Etan Cohen
12901da4332949ad1053078053097bfc59a72653f477Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
12911da4332949ad1053078053097bfc59a72653f477Etan Cohen    }
12921da4332949ad1053078053097bfc59a72653f477Etan Cohen
12931da4332949ad1053078053097bfc59a72653f477Etan Cohen    /**
12941da4332949ad1053078053097bfc59a72653f477Etan Cohen     * Validate that when sending a message with a retry count the message is retried the specified
12951da4332949ad1053078053097bfc59a72653f477Etan Cohen     * number of times. Scenario ending with failure.
12961da4332949ad1053078053097bfc59a72653f477Etan Cohen     */
12971da4332949ad1053078053097bfc59a72653f477Etan Cohen    @Test
12981da4332949ad1053078053097bfc59a72653f477Etan Cohen    public void testSendMessageRetransmitFail() throws Exception {
12991da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int clientId = 1005;
13001da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String ssi = "some much longer and more arbitrary data";
13011da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int subscribeId = 15;
13021da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int requestorId = 22;
13031da4332949ad1053078053097bfc59a72653f477Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
13041da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerSsi = "some peer ssi data";
13051da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
13061da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int messageId = 6948;
13071da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int retryCount = 3;
13081da4332949ad1053078053097bfc59a72653f477Etan Cohen
13091da4332949ad1053078053097bfc59a72653f477Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
13101da4332949ad1053078053097bfc59a72653f477Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
13111da4332949ad1053078053097bfc59a72653f477Etan Cohen
13121da4332949ad1053078053097bfc59a72653f477Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
13131da4332949ad1053078053097bfc59a72653f477Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
13141da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
13151da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
13161da4332949ad1053078053097bfc59a72653f477Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
13171da4332949ad1053078053097bfc59a72653f477Etan Cohen
1318b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1319b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1320b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1321b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
13221da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (1) connect
13231da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.connect(clientId, mockCallback, configRequest);
13241da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13251da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
13261da4332949ad1053078053097bfc59a72653f477Etan Cohen                eq(true));
13271da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
13281da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13291da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
13301da4332949ad1053078053097bfc59a72653f477Etan Cohen
13311da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (2) subscribe & match
13321da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
13331da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13341da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
13351da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
13361da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
13371da4332949ad1053078053097bfc59a72653f477Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
13381da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13391da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
13401da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
13411da4332949ad1053078053097bfc59a72653f477Etan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
13421da4332949ad1053078053097bfc59a72653f477Etan Cohen
13431da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (3) send message and enqueue successfully
13441da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
13451da4332949ad1053078053097bfc59a72653f477Etan Cohen                ssi.length(), messageId, retryCount);
13461da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13471da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
13481da4332949ad1053078053097bfc59a72653f477Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
13491da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
13501da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
13511da4332949ad1053078053097bfc59a72653f477Etan Cohen
13521da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (4) loop and fail until reach retryCount+1
13531da4332949ad1053078053097bfc59a72653f477Etan Cohen        for (int i = 0; i < retryCount + 1; ++i) {
13541da4332949ad1053078053097bfc59a72653f477Etan Cohen            mDut.onMessageSendFailNotification(transactionId.getValue(),
13551da4332949ad1053078053097bfc59a72653f477Etan Cohen                    WifiNanSessionCallback.REASON_TX_FAIL);
13561da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
13571da4332949ad1053078053097bfc59a72653f477Etan Cohen
13581da4332949ad1053078053097bfc59a72653f477Etan Cohen            if (i != retryCount) {
13591da4332949ad1053078053097bfc59a72653f477Etan Cohen                inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
13601da4332949ad1053078053097bfc59a72653f477Etan Cohen                        eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
13611da4332949ad1053078053097bfc59a72653f477Etan Cohen                mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
13621da4332949ad1053078053097bfc59a72653f477Etan Cohen                mMockLooper.dispatchAll();
13631da4332949ad1053078053097bfc59a72653f477Etan Cohen            }
13641da4332949ad1053078053097bfc59a72653f477Etan Cohen        }
13651da4332949ad1053078053097bfc59a72653f477Etan Cohen
13661da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
13671da4332949ad1053078053097bfc59a72653f477Etan Cohen                WifiNanSessionCallback.REASON_TX_FAIL);
13681da4332949ad1053078053097bfc59a72653f477Etan Cohen
13691da4332949ad1053078053097bfc59a72653f477Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
13701bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    }
13711bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
13721bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    /**
13737335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     * Validate that start ranging function fills-in correct MAC addresses for peer IDs and
13747335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     * passed along to RTT module.
13757335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     */
13767335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    @Test
13777335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    public void testStartRanging() throws Exception {
13787335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int clientId = 1005;
13797335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int subscribeId = 15;
13807335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int requestorId = 22;
13817335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
13827335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final String peerSsi = "some peer ssi data";
13837335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final String peerMatchFilter = "filter binary array represented as string";
13847335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int rangingId = 18423;
13857335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final RttManager.RttParams[] params = new RttManager.RttParams[2];
13867335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[0] = new RttManager.RttParams();
13877335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[0].bssid = Integer.toString(requestorId);
13887335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[1] = new RttManager.RttParams();
13897335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[1].bssid = Integer.toString(requestorId + 5);
13907335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
13917335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
13927335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
13937335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
13947335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
13957335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
13967335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
13977335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
13987335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
13997335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<WifiNanClientState> clientCaptor =
14007335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                ArgumentCaptor.forClass(WifiNanClientState.class);
14017335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<RttManager.RttParams[]> rttParamsCaptor =
14027335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                ArgumentCaptor.forClass(RttManager.RttParams[].class);
14037335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
14047335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative,
14057335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                mMockNanRttStateManager);
14067335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
1407b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1408b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1409b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1410b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
14117335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (1) connect
14127335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
14137335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
14147335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
14157335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                eq(true));
14167335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
14177335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
14187335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
14197335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
14207335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (2) subscribe & match
14217335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
14227335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
14237335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
14247335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
14257335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
14267335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
14277335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
14287335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
14297335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
14307335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
14317335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
14327335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (3) start ranging: pass along a valid peer ID and an invalid one
14337335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.startRanging(clientId, sessionId.getValue(), params, rangingId);
14347335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
14357335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mMockNanRttStateManager).startRanging(eq(rangingId), clientCaptor.capture(),
14367335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                rttParamsCaptor.capture());
14377335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        collector.checkThat("RttParams[0].bssid", "06:07:08:09:0A:0B",
14387335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                equalTo(rttParamsCaptor.getValue()[0].bssid));
14397335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        collector.checkThat("RttParams[1].bssid", "", equalTo(rttParamsCaptor.getValue()[1].bssid));
14407335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
14417335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative,
14427335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                mMockNanRttStateManager);
14437335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    }
14447335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
14457335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    /**
14469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Test sequence of configuration: (1) config1, (2) config2 - incompatible,
14479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * (3) config3 - compatible with config1 (requiring upgrade), (4) disconnect
14489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * config3 (should get a downgrade), (5) disconnect config1 (should get a
14499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * disable).
14509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
1451cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    @Test
1452956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void testConfigs() throws Exception {
1453c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId1 = 9999;
1454956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int clusterLow1 = 5;
1455956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int clusterHigh1 = 100;
1456956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int masterPref1 = 111;
1457c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId2 = 1001;
1458956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final boolean support5g2 = true;
1459956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int clusterLow2 = 7;
1460956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int clusterHigh2 = 155;
1461956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int masterPref2 = 0;
1462c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId3 = 55;
1463956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1464956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1465956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<ConfigRequest> crCapture = ArgumentCaptor.forClass(ConfigRequest.class);
1466956f54b391677d78379729dd14518edddf3c7660Etan Cohen
146722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
14689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1)
14699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setEnableIdentityChangeCallback(false).build();
1470956f54b391677d78379729dd14518edddf3c7660Etan Cohen
147122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest2 = new ConfigRequest.Builder().setSupport5gBand(support5g2)
147222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterLow(clusterLow2).setClusterHigh(clusterHigh2)
147322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setMasterPreference(masterPref2).build();
1474956f54b391677d78379729dd14518edddf3c7660Etan Cohen
14759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest3 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
14769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1)
14779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .setEnableIdentityChangeCallback(true).build();
1478956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1479676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback1 = mock(IWifiNanEventCallback.class);
1480676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback2 = mock(IWifiNanEventCallback.class);
1481676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback3 = mock(IWifiNanEventCallback.class);
1482956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1483676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback1, mockCallback2, mockCallback3);
1484956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1485b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1486b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1487b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1488b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
14899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) config1 (valid)
14909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId1, mockCallback1, configRequest1);
1491956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
1492956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
14939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                crCapture.capture(), eq(true));
14949864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 1", crCapture.getValue(), equalTo(configRequest1));
14959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1496956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
14979864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback1).onConnectSuccess();
1498956f54b391677d78379729dd14518edddf3c7660Etan Cohen
14999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) config2 (incompatible with config1)
15009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId2, mockCallback2, configRequest2);
1501956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
15029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback2)
15039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .onConnectFail(WifiNanEventCallback.REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG);
15049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId2);
1505956f54b391677d78379729dd14518edddf3c7660Etan Cohen
15069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) config3 (compatible with config1 but requires upgrade - i.e. no
15079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // OTA changes)
15089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId3, mockCallback3, configRequest3);
1509956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
1510956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
15119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                crCapture.capture(), eq(false));
15129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 3: support 5g", crCapture.getValue().mSupport5gBand,
15139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(false));
15149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 3: master pref", crCapture.getValue().mMasterPreference,
15159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(masterPref1));
15169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 3: cluster low", crCapture.getValue().mClusterLow,
15179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(clusterLow1));
15189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 3: cluster high", crCapture.getValue().mClusterHigh,
15199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(clusterHigh1));
15209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 3: enable identity change callback",
15219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                crCapture.getValue().mEnableIdentityChangeCallback, equalTo(true));
15229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
15239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
15249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback3).onConnectSuccess();
15259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
15269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) disconnect config3: want a downgrade
15279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId3);
1528956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
15299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId3);
1530956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
15319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                crCapture.capture(), eq(false));
15329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 4", crCapture.getValue(), equalTo(configRequest1));
15339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1534956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
1535956f54b391677d78379729dd14518edddf3c7660Etan Cohen
15369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (5) disconnect config1: disable
1537c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        mDut.disconnect(clientId1);
1538956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
15399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId1);
15409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
1541956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1542ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback1, mockCallback2, mockCallback3);
1543956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
1544956f54b391677d78379729dd14518edddf3c7660Etan Cohen
154522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
154622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: disconnect a client while there are pending transactions.
154722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
154822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
154922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testDisconnectWithPendingTransactions() throws Exception {
1550c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 125;
155122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 5;
155222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 100;
155322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 111;
155422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
155522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String ssi = "some much longer and more arbitrary data";
155622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishCount = 7;
1557676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        final int reason = WifiNanSessionCallback.TERMINATE_REASON_DONE;
155822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 22;
155922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
156022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
156122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
156222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
15638f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
15648f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setServiceSpecificInfo(ssi).setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED)
156522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setPublishCount(publishCount).build();
156622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
156722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1568676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1569676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
1570676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1571676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
1572b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1573b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1574b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1575b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
15769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
15779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
15789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
15799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
15809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
15819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
15829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
15839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
15849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
15859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish (no response yet)
158612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
158722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
15889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
158922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
15909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) disconnect (but doesn't get executed until get a RESPONSE to the
15919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // previous publish)
15929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
15939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
159422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
15959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) get successful response to the publish
15969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
15979864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1598ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
15999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).stopPublish((short) 0, publishId);
16009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
160122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1602c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        validateInternalClientInfoCleanedUp(clientId);
160322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
16049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (5) trying to publish on the same client: NOP
16059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
160622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
160722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
16089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (6) got some callback on original publishId - should be ignored
16099864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(publishId, reason, true);
161022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
161122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1612ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
161322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
161422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
161522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
16164f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that an unknown transaction (i.e. a callback from HAL with an
16174f1887493430b6b61126f233f3de54201b363145Etan Cohen     * unknown type) is simply ignored - but also cleans up its state.
16184f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
16194f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
16204f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testUnknownTransactionType() throws Exception {
16214f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 129;
16224f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clusterLow = 15;
16234f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clusterHigh = 192;
16244f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int masterPref = 234;
16254f1887493430b6b61126f233f3de54201b363145Etan Cohen        final String serviceName = "some-service-name";
16264f1887493430b6b61126f233f3de54201b363145Etan Cohen        final String ssi = "some much longer and more arbitrary data";
16274f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int publishCount = 15;
16284f1887493430b6b61126f233f3de54201b363145Etan Cohen
16294f1887493430b6b61126f233f3de54201b363145Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
16304f1887493430b6b61126f233f3de54201b363145Etan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
16314f1887493430b6b61126f233f3de54201b363145Etan Cohen
16324f1887493430b6b61126f233f3de54201b363145Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
16334f1887493430b6b61126f233f3de54201b363145Etan Cohen                .setServiceSpecificInfo(ssi).setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED)
16344f1887493430b6b61126f233f3de54201b363145Etan Cohen                .setPublishCount(publishCount).build();
16354f1887493430b6b61126f233f3de54201b363145Etan Cohen
16364f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
16374f1887493430b6b61126f233f3de54201b363145Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
16384f1887493430b6b61126f233f3de54201b363145Etan Cohen        IWifiNanSessionCallback mockPublishSessionCallback = mock(IWifiNanSessionCallback.class);
16394f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockPublishSessionCallback);
16404f1887493430b6b61126f233f3de54201b363145Etan Cohen
1641b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1642b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1643b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1644b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
16459864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
16469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
16479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
16489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
16499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
16509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
16514f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
1652ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
16534f1887493430b6b61126f233f3de54201b363145Etan Cohen
16549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish - no response
16559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockPublishSessionCallback);
16564f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
16579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
16584f1887493430b6b61126f233f3de54201b363145Etan Cohen
1659ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockPublishSessionCallback);
16604f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
16614f1887493430b6b61126f233f3de54201b363145Etan Cohen
16624f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
16634f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that a NoOp transaction (i.e. a callback from HAL which doesn't
16644f1887493430b6b61126f233f3de54201b363145Etan Cohen     * require any action except clearing up state) actually cleans up its state
16654f1887493430b6b61126f233f3de54201b363145Etan Cohen     * (and does nothing else).
16664f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
16674f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
16684f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testNoOpTransaction() throws Exception {
16694f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 1294;
16704f1887493430b6b61126f233f3de54201b363145Etan Cohen
16719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
16724f1887493430b6b61126f233f3de54201b363145Etan Cohen
16734f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
16744f1887493430b6b61126f233f3de54201b363145Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
16754f1887493430b6b61126f233f3de54201b363145Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
16764f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
16774f1887493430b6b61126f233f3de54201b363145Etan Cohen
1678b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1679b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1680b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1681b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
16829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect (no response)
16839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
16844f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
16859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
16869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
16874f1887493430b6b61126f233f3de54201b363145Etan Cohen
1688ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
16894f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
16904f1887493430b6b61126f233f3de54201b363145Etan Cohen
16914f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
16924f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that getting callbacks from HAL with unknown (expired)
16934f1887493430b6b61126f233f3de54201b363145Etan Cohen     * transaction ID or invalid publish/subscribe ID session doesn't have any
16944f1887493430b6b61126f233f3de54201b363145Etan Cohen     * impact.
16954f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
16964f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
16974f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testInvalidCallbackIdParameters() throws Exception {
16989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int pubSubId = 1235;
16994f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 132;
17004f1887493430b6b61126f233f3de54201b363145Etan Cohen
17014f1887493430b6b61126f233f3de54201b363145Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
17024f1887493430b6b61126f233f3de54201b363145Etan Cohen
17034f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
17044f1887493430b6b61126f233f3de54201b363145Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
17054f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback);
17064f1887493430b6b61126f233f3de54201b363145Etan Cohen
1707b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1708b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1709b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1710b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
17119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect and succeed
17129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
17134f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
17149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
17159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
17164f1887493430b6b61126f233f3de54201b363145Etan Cohen        short transactionIdConfig = transactionId.getValue();
17179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionIdConfig);
17184f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
17199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
17204f1887493430b6b61126f233f3de54201b363145Etan Cohen
17219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) use the same transaction ID to send a bunch of other responses
17229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionIdConfig);
17239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigFailedResponse(transactionIdConfig, -1);
17249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionIdConfig, true, -1);
17251bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdConfig);
17261bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedFailResponse(transactionIdConfig, -1);
17279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionIdConfig, false, -1);
17289864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMatchNotification(-1, -1, new byte[0], new byte[0], 0, new byte[0], 0);
17299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(-1, -1, true);
17309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(-1, -1, false);
17319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMessageReceivedNotification(-1, -1, new byte[0], new byte[0], 0);
17329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionIdConfig, true, pubSubId);
17339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionIdConfig, false, pubSubId);
17344f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
17354f1887493430b6b61126f233f3de54201b363145Etan Cohen
1736ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
17374f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
17384f1887493430b6b61126f233f3de54201b363145Etan Cohen
17394f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
174012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate that trying to update-subscribe on a publish session fails.
1741e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     */
1742e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    @Test
1743e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    public void testSubscribeOnPublishSessionType() throws Exception {
1744e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        final int clientId = 188;
174512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 25;
1746e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
17479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
1748e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
1749e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1750e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
1751e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
175212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1753e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1754e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
1755e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1756e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
1757b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1758b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1759b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1760b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
17619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
17629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
17639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
17649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
17659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(true));
17669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1767e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
17689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
1769e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
17709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
17719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
17729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1773e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
17749864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
177512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
177612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
177712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
17789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) update-subscribe -> failure
177912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
1780e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
1781e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        inOrder.verify(mockSessionCallback)
17829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
17839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
1784ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
1785e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    }
1786e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
1787e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    /**
1788e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     * Validate that trying to (re)subscribe on a publish session or (re)publish
1789e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     * on a subscribe session fails.
1790e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     */
1791e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    @Test
1792e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    public void testPublishOnSubscribeSessionType() throws Exception {
1793e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        final int clientId = 188;
179412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 25;
1795e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
17969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
1797e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
1798e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1799e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
1800e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
180112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1802e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
1803e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
1804e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1805e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
1806b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1807b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1808b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1809b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
18109864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
18119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
1812e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
18139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
18149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest), eq(true));
18159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
18169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
18179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
1818e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
18199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) subscribe
18209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
18219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1822e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
18239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
182412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
182512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
182612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
18279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) update-publish -> error
182812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
1829e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
18309cf66a4b8313520a6967eb5491459e7bebd3a718Etan Cohen        inOrder.verify(mockSessionCallback)
18319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
18329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
1833ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
1834e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    }
1835e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
18369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
18379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validate that the session ID increments monotonically
18389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
183922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
18409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public void testSessionIdIncrement() throws Exception {
18419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId = 188;
184222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        int loopCount = 100;
184322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
18449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
18459864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
18469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
18479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
18489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
18499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
18509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
18519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
18529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
1853b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1854b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1855b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        inOrder.verify(mMockNative).getCapabilities(anyShort());
1856b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
18579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
18589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.connect(clientId, mockCallback, configRequest);
18599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
18609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
18619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                eq(configRequest), eq(true));
18629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
18639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
18649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockCallback).onConnectSuccess();
18659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
18669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        int prevId = 0;
186722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        for (int i = 0; i < loopCount; ++i) {
18689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            // (2) publish
18699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mDut.publish(clientId, publishConfig, mockSessionCallback);
18709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mMockLooper.dispatchAll();
18719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
18729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
18739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            // (3) publish-success
18749864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, i + 1);
18759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mMockLooper.dispatchAll();
18769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
18779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
187822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen            if (i != 0) {
18799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                assertTrue("Session ID incrementing", sessionId.getValue() > prevId);
188022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen            }
18819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            prevId = sessionId.getValue();
188222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        }
188322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
188422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
188522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /*
188622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Tests of internal state of WifiNanStateManager: very limited (not usually
188722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * a good idea). However, these test that the internal state is cleaned-up
188822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * appropriately. Alternatively would cause issues with memory leaks or
188922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * information leak between sessions.
189022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
189122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
189222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
189322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Utility routine used to validate that the internal state is cleaned-up
189422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * after a client is disconnected. To be used in every test which terminates
189522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * a client.
189622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     *
1897c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param clientId The ID of the client which should be deleted.
189822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
1899b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalClientInfoCleanedUp(int clientId) throws Exception {
1900c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        WifiNanClientState client = getInternalClientState(mDut, clientId);
1901c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        collector.checkThat("Client record not cleared up for clientId=" + clientId, client,
1902c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen                nullValue());
190312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
190412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
190512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
190612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Utility routine used to validate that the internal state is cleaned-up
190712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (deleted) after a session is terminated through API (not callback!). To
190812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * be used in every test which terminates a session.
190912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *
191012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param clientId The ID of the client containing the session.
191112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param sessionId The ID of the terminated session.
191212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
1913b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalSessionInfoCleanedUp(int clientId, int sessionId)
1914b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen            throws Exception {
191512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        WifiNanClientState client = getInternalClientState(mDut, clientId);
191612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
191712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        WifiNanSessionState session = getInternalSessionState(client, sessionId);
191812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        collector.checkThat("Client record not cleaned-up for sessionId=" + sessionId, session,
191912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                nullValue());
19209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    }
192112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
19229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
19239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Utility routine used to validate that the internal state is cleaned-up
19249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * (deleted) correctly. Checks that a specific client has no sessions
19259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * attached to it.
19269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     *
19279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * @param clientId The ID of the client which we want to check.
19289864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
1929b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalNoSessions(int clientId) throws Exception {
19309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        WifiNanClientState client = getInternalClientState(mDut, clientId);
19319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
19329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
19339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        Field field = WifiNanClientState.class.getDeclaredField("mSessions");
19349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        field.setAccessible(true);
19359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        @SuppressWarnings("unchecked")
19369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        SparseArray<WifiNanSessionState> sessions = (SparseArray<WifiNanSessionState>) field
19379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                .get(client);
19389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
19399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("No sessions exist for clientId=" + clientId, sessions.size(),
19409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(0));
194122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
194222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
19431b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
19441b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     * Validates that the broadcast sent on NAN status change is correct.
19451b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     *
19461b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     * @param expectedEnabled The expected change status - i.e. are we expected
19471b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     *            to announce that NAN is enabled (true) or disabled (false).
19481b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
1949b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateCorrectNanStatusChangeBroadcast(InOrder inOrder, boolean expectedEnabled) {
19501b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
19511b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
19521b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL));
19531b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
19541b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("intent action", intent.getValue().getAction(),
19551b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                equalTo(WifiNanManager.WIFI_NAN_STATE_CHANGED_ACTION));
19561b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("intent contains wifi status key",
19571b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                intent.getValue().getExtras().containsKey(WifiNanManager.EXTRA_WIFI_STATE),
19581b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                equalTo(true));
19591b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("intnent wifi status key value",
19601b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                intent.getValue().getExtras().getInt(WifiNanManager.EXTRA_WIFI_STATE),
19611b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                equalTo(expectedEnabled ? WifiNanManager.WIFI_NAN_STATE_ENABLED
19621b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                        : WifiNanManager.WIFI_NAN_STATE_DISABLED));
19631b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
19641b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1965956f54b391677d78379729dd14518edddf3c7660Etan Cohen    /*
1966956f54b391677d78379729dd14518edddf3c7660Etan Cohen     * Utilities
1967956f54b391677d78379729dd14518edddf3c7660Etan Cohen     */
1968956f54b391677d78379729dd14518edddf3c7660Etan Cohen
19697335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    private static WifiNanStateManager installNewNanStateManagerAndResetState(
19707335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen            WifiNanRttStateManager mockRtt) throws Exception {
1971956f54b391677d78379729dd14518edddf3c7660Etan Cohen        Constructor<WifiNanStateManager> ctr = WifiNanStateManager.class.getDeclaredConstructor();
1972956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ctr.setAccessible(true);
1973956f54b391677d78379729dd14518edddf3c7660Etan Cohen        WifiNanStateManager nanStateManager = ctr.newInstance();
1974956f54b391677d78379729dd14518edddf3c7660Etan Cohen
197522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton");
1976956f54b391677d78379729dd14518edddf3c7660Etan Cohen        field.setAccessible(true);
1977956f54b391677d78379729dd14518edddf3c7660Etan Cohen        field.set(null, nanStateManager);
1978956f54b391677d78379729dd14518edddf3c7660Etan Cohen
19797335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        field = WifiNanStateManager.class.getDeclaredField("mRtt");
19807335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        field.setAccessible(true);
19817335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        field.set(nanStateManager, mockRtt);
19827335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
1983956f54b391677d78379729dd14518edddf3c7660Etan Cohen        return WifiNanStateManager.getInstance();
1984956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
1985956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1986956f54b391677d78379729dd14518edddf3c7660Etan Cohen    private static void installMockWifiNanNative(WifiNanNative obj) throws Exception {
1987956f54b391677d78379729dd14518edddf3c7660Etan Cohen        Field field = WifiNanNative.class.getDeclaredField("sWifiNanNativeSingleton");
1988956f54b391677d78379729dd14518edddf3c7660Etan Cohen        field.setAccessible(true);
1989956f54b391677d78379729dd14518edddf3c7660Etan Cohen        field.set(null, obj);
1990956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
199122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1992c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen    private static WifiNanClientState getInternalClientState(WifiNanStateManager dut, int clientId)
1993c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen            throws Exception {
199422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        Field field = WifiNanStateManager.class.getDeclaredField("mClients");
199522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        field.setAccessible(true);
199622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        @SuppressWarnings("unchecked")
199722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        SparseArray<WifiNanClientState> clients = (SparseArray<WifiNanClientState>) field.get(dut);
199822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1999c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        return clients.get(clientId);
200022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
200112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
200212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    private static WifiNanSessionState getInternalSessionState(WifiNanClientState client,
200312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen            int sessionId) throws Exception {
200412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        Field field = WifiNanClientState.class.getDeclaredField("mSessions");
200512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        field.setAccessible(true);
200612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        @SuppressWarnings("unchecked")
200712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SparseArray<WifiNanSessionState> sessions = (SparseArray<WifiNanSessionState>) field
200812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                .get(client);
200912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
201012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        return sessions.get(sessionId);
201112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
2012956f54b391677d78379729dd14518edddf3c7660Etan Cohen}
201322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2014