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
17c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenpackage com.android.server.wifi.aware;
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;
2226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohenimport static org.junit.Assert.assertEquals;
2322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenimport static org.junit.Assert.assertTrue;
249fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.any;
259fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.anyBoolean;
269fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.anyInt;
279fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.anyShort;
289fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.eq;
299fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohenimport static org.mockito.ArgumentMatchers.isNull;
30956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.inOrder;
31956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.mock;
329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohenimport static org.mockito.Mockito.times;
33e27021e4c8c369554880ab522a1e27942b15687bEtan Cohenimport static org.mockito.Mockito.verify;
34956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport static org.mockito.Mockito.verifyNoMoreInteractions;
351b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport static org.mockito.Mockito.when;
36956f54b391677d78379729dd14518edddf3c7660Etan Cohen
37ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohenimport android.Manifest;
38ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohenimport android.app.AppOpsManager;
39b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohenimport android.app.test.MockAnswerUtil;
40b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohenimport android.app.test.TestAlarmManager;
411b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.content.Context;
421b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.content.Intent;
43ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohenimport android.content.pm.PackageManager;
44db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanStatusType;
457124382d477741945bdd3af7fec99b702fd1fc23Etan Cohenimport android.net.ConnectivityManager;
467335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohenimport android.net.wifi.RttManager;
47c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.ConfigRequest;
48c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
49c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.IWifiAwareEventCallback;
50c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.PublishConfig;
51c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.SubscribeConfig;
52c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenimport android.net.wifi.aware.WifiAwareManager;
53e27021e4c8c369554880ab522a1e27942b15687bEtan Cohenimport android.os.Message;
541b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohenimport android.os.UserHandle;
55f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.os.test.TestLooper;
56956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport android.test.suitebuilder.annotation.SmallTest;
57e27021e4c8c369554880ab522a1e27942b15687bEtan Cohenimport android.util.Log;
5822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohenimport android.util.SparseArray;
59956f54b391677d78379729dd14518edddf3c7660Etan Cohen
60956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport libcore.util.HexEncoding;
61956f54b391677d78379729dd14518edddf3c7660Etan Cohen
62956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Before;
63956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Rule;
64956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.Test;
65956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.junit.rules.ErrorCollector;
66956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.ArgumentCaptor;
67956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.InOrder;
68956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.Mock;
69956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport org.mockito.MockitoAnnotations;
70956f54b391677d78379729dd14518edddf3c7660Etan Cohen
7149a847941e08faec5901d4824040a522b773ef83Etan Cohenimport java.io.PrintWriter;
7249a847941e08faec5901d4824040a522b773ef83Etan Cohenimport java.io.StringWriter;
73956f54b391677d78379729dd14518edddf3c7660Etan Cohenimport java.lang.reflect.Field;
7426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohenimport java.util.HashMap;
7526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohenimport java.util.HashSet;
7626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohenimport java.util.LinkedList;
77e27021e4c8c369554880ab522a1e27942b15687bEtan Cohenimport java.util.Map;
78e27021e4c8c369554880ab522a1e27942b15687bEtan Cohenimport java.util.Random;
7926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohenimport java.util.Set;
80956f54b391677d78379729dd14518edddf3c7660Etan Cohen
81956f54b391677d78379729dd14518edddf3c7660Etan Cohen/**
82c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen * Unit test harness for WifiAwareStateManager.
83956f54b391677d78379729dd14518edddf3c7660Etan Cohen */
84956f54b391677d78379729dd14518edddf3c7660Etan Cohen@SmallTest
85c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohenpublic class WifiAwareStateManagerTest {
86f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    private TestLooper mMockLooper;
87e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    private Random mRandomNg = new Random(15687);
88c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private WifiAwareStateManager mDut;
89db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    @Mock private WifiAwareNativeApi mMockNative;
901b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Mock private Context mMockContext;
91ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen    @Mock private AppOpsManager mMockAppOpsManager;
92c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    @Mock private WifiAwareRttStateManager mMockAwareRttStateManager;
93f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestAlarmManager mAlarmManager;
94c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    @Mock private WifiAwareDataPathStateManager mMockAwareDataPathStatemanager;
95956f54b391677d78379729dd14518edddf3c7660Etan Cohen
96956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Rule
97956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public ErrorCollector collector = new ErrorCollector();
98956f54b391677d78379729dd14518edddf3c7660Etan Cohen
99ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen    private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0};
100ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
1019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
1029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Pre-test configuration. Initialize and install mocks.
1039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
104956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Before
105956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void setUp() throws Exception {
106956f54b391677d78379729dd14518edddf3c7660Etan Cohen        MockitoAnnotations.initMocks(this);
107956f54b391677d78379729dd14518edddf3c7660Etan Cohen
108f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mAlarmManager = new TestAlarmManager();
1094375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        when(mMockContext.getSystemService(Context.ALARM_SERVICE))
1104375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen                .thenReturn(mAlarmManager.getAlarmManager());
1114375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
1127124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen        when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
1137124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen                mock(ConnectivityManager.class));
114ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
115ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockContext.checkPermission(eq(android.Manifest.permission.ACCESS_FINE_LOCATION),
116ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
117ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockContext.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION),
118ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
119ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockAppOpsManager.noteOp(eq(AppOpsManager.OP_FINE_LOCATION), anyInt(),
1209fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any())).thenReturn(AppOpsManager.MODE_ERRORED);
121ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockAppOpsManager.noteOp(eq(AppOpsManager.OP_COARSE_LOCATION), anyInt(),
1229fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any())).thenReturn(AppOpsManager.MODE_ERRORED);
1237124382d477741945bdd3af7fec99b702fd1fc23Etan Cohen
124f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mMockLooper = new TestLooper();
125956f54b391677d78379729dd14518edddf3c7660Etan Cohen
126d45abba86c33bd93863fc9d8f7c84ca28deb17b2Etan Cohen        mDut = new WifiAwareStateManager();
127d45abba86c33bd93863fc9d8f7c84ca28deb17b2Etan Cohen        mDut.setNative(mMockNative);
1281b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.start(mMockContext, mMockLooper.getLooper());
129c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        installMocksInStateManager(mDut, mMockAwareRttStateManager, mMockAwareDataPathStatemanager);
1301b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1319fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.enableAndConfigure(anyShort(), any(), anyBoolean(),
132db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                anyBoolean())).thenReturn(true);
1331b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.disable(anyShort())).thenReturn(true);
1349fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.publish(anyShort(), anyInt(), any())).thenReturn(true);
1359fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.subscribe(anyShort(), anyInt(), any()))
1361b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen                .thenReturn(true);
1379fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(),
1389fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any(), anyInt())).thenReturn(true);
1391b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.stopPublish(anyShort(), anyInt())).thenReturn(true);
1401b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        when(mMockNative.stopSubscribe(anyShort(), anyInt())).thenReturn(true);
141e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        when(mMockNative.getCapabilities(anyShort())).thenReturn(true);
142956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
143956f54b391677d78379729dd14518edddf3c7660Etan Cohen
14412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
145c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen     * Validate that Aware data-path interfaces are brought up and down correctly.
146b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen     */
147b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen    @Test
148c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    public void testAwareDataPathInterfaceUpDown() throws Exception {
149b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
150c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mMockAwareDataPathStatemanager);
151b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen
152b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        // (1) enable usage
153b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        mDut.enableUsage();
154b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        mMockLooper.dispatchAll();
155c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, true);
156b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
157e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
158e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
159c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        inOrder.verify(mMockAwareDataPathStatemanager).createAllInterfaces();
160b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
161b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen
162b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        // (2) disable usage
163b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        mDut.disableUsage();
164b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        mMockLooper.dispatchAll();
165c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        inOrder.verify(mMockAwareDataPathStatemanager).onAwareDownCleanupDataPaths();
166b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        inOrder.verify(mMockNative).disable((short) 0);
167c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, false);
168c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        inOrder.verify(mMockAwareDataPathStatemanager).deleteAllInterfaces();
169b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
170b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen
171c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        verifyNoMoreInteractions(mMockNative, mMockAwareDataPathStatemanager);
172b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen    }
173b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen
174b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen    /**
1751b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     * Validate that APIs aren't functional when usage is disabled.
1761b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
1771b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Test
1781b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    public void testDisableUsageDisablesApis() throws Exception {
1791b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final int clientId = 12314;
1807cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
181ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
182ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
1831b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
1841b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
185c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1861b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
1871b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
188e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
189b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
1901b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (1) check initial state
191e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.enableUsage();
192e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
193c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, true);
194e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
195e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
196e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1971b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
1981b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
1991b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (2) disable usage and validate state
2001b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
2011b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2021b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
2031b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).disable((short) 0);
204c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, false);
2051b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
206f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen        // (3) try connecting and validate that get nothing (app should be aware of non-availability
207f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen        // through state change broadcast and/or query API)
208f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
2091b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2101b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2111bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
2121b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
2131b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2141b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
215f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * Validate that when API usage is disabled while in the middle of a connection that internal
216f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * state is cleaned-up, and that all subsequent operations are NOP. Then enable usage again and
217f1aa2b3fddc1b3e261ea54635f148fdc120ae7cbEtan Cohen     * validate that operates correctly.
2181b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
2191b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    @Test
2201b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    public void testDisableUsageFlow() throws Exception {
2211b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final int clientId = 12341;
2227cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
223ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
224ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
2251b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
2261b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
227c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2281b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2291b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
2301b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
231e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        // (1) check initial state
232b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
233b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
234c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, true);
235e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
236e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
237e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
238e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2391b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
2401b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2411b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (2) connect (successfully)
242f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
2431b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2441b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
245db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
2461b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
2471b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
248b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
2491b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2501b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (3) disable usage & verify callbacks
2511b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
2521b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2531b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
2541b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).disable((short) 0);
255c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, false);
2561b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        validateInternalClientInfoCleanedUp(clientId);
2571b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
258c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        // (4) try connecting again and validate that just get an onAwareDown
259f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
2601b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2611b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2621b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (5) disable usage again and validate that not much happens
2631b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.disableUsage();
2641b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2651b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
2661b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2671b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (6) enable usage
2681b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.enableUsage();
2691b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2701b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
271c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, true);
2721b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2731b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        // (7) connect (should be successful)
274f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
2751b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
2761b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
277db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
2781b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
2791b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        mMockLooper.dispatchAll();
280b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
2811b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
282ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
2831b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
2841b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2851b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
2865254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * Validates that a HAL failure on enable and configure results in failed callback.
2875254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     */
2885254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen    @Test
2895254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen    public void testHalFailureEnableAndConfigure() throws Exception {
2905254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        final int clientId = 12341;
2915254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        final int uid = 1000;
2925254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        final int pid = 2000;
2935254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        final String callingPackage = "com.google.somePackage";
2945254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
2955254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
2965254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2975254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2985254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
2995254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
3009fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.enableAndConfigure(anyShort(), any(), anyBoolean(),
3015254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                anyBoolean())).thenReturn(false);
3025254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
3035254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (1) check initial state
3045254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.enableUsage();
3055254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
3065254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        validateCorrectAwareStatusChangeBroadcast(inOrder, true);
3075254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
3085254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
3095254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
3105254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
3115254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (2) connect with HAL failure
3125254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
3135254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
3145254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
3155254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                eq(false), eq(true));
3165254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mockCallback).onConnectFail(NanStatusType.INTERNAL_FAILURE);
3175254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
3185254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        validateInternalClientInfoCleanedUp(clientId);
3195254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
3205254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen    }
3215254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
3225254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen    /**
3239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validates that all events are delivered with correct arguments. Validates
3249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * that IdentityChanged not delivered if configuration disables delivery.
32512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
326956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
327c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    public void testAwareEventsDelivery() throws Exception {
3289864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId1 = 1005;
3299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId2 = 1007;
330c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int clusterLow = 5;
331c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int clusterHigh = 100;
332c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen        final int masterPref = 111;
3337cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
334ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
335ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
336db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reason = NanStatusType.INTERNAL_FAILURE;
337956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
338ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final byte[] someMac2 = HexEncoding.decode("060708090A0B".toCharArray(), false);
339956f54b391677d78379729dd14518edddf3c7660Etan Cohen
340f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
341c9ac67224dcf7a41692256c338188206f4f29f5cEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
342f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen                .build();
34322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
344c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
345c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
3469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
3479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
348956f54b391677d78379729dd14518edddf3c7660Etan Cohen
349b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
350b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
351e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionIdCapture.capture());
352e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionIdCapture.getValue(), getCapabilities());
353e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
354b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
3559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect 1st and 2nd clients
356f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId1, uid, pid, callingPackage, mockCallback1, configRequest, false);
3579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
3589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
359db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
3609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        short transactionId = transactionIdCapture.getValue();
3619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId);
36222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
363b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback1).onConnectSuccess(clientId1);
364db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
365db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mDut.connect(clientId2, uid, pid, callingPackage, mockCallback2, configRequest, true);
366db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mMockLooper.dispatchAll();
367db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
368db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(true), eq(false));
369db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        transactionId = transactionIdCapture.getValue();
370db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mDut.onConfigSuccessResponse(transactionId);
371db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mMockLooper.dispatchAll();
372b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback2).onConnectSuccess(clientId2);
373ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
374c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        // (2) deliver Aware events - without LOCATIONING permission
375c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        mDut.onClusterChangeNotification(WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED,
376c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                someMac);
3779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onInterfaceAddressChangeNotification(someMac);
37822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
37922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
380ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        inOrder.verify(mockCallback2).onIdentityChanged(ALL_ZERO_MAC);
381ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
382f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        // (3) deliver new identity - still without LOCATIONING permission (should get an event)
383ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mDut.onInterfaceAddressChangeNotification(someMac2);
384ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mMockLooper.dispatchAll();
385ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
386ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        inOrder.verify(mockCallback2).onIdentityChanged(ALL_ZERO_MAC);
387ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
388f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        // (4) deliver same identity - still without LOCATIONING permission (should
389ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        // not get an event)
390ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mDut.onInterfaceAddressChangeNotification(someMac2);
391ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mMockLooper.dispatchAll();
392ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
393f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        // (5) deliver new identity - with LOCATIONING permission
394ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockContext.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION),
395ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
396ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        when(mMockAppOpsManager.noteOp(eq(AppOpsManager.OP_COARSE_LOCATION), anyInt(),
3979fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any())).thenReturn(AppOpsManager.MODE_ALLOWED);
398ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mDut.onInterfaceAddressChangeNotification(someMac);
399ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mMockLooper.dispatchAll();
400ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
401d2683c76cbe9a518b8e9e8b1c1a725c77c1858e5Etan Cohen        inOrder.verify(mockCallback2).onIdentityChanged(someMac);
402956f54b391677d78379729dd14518edddf3c7660Etan Cohen
403c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        // (6) Aware down (no feedback)
404c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        mDut.onAwareDownNotification(reason);
405ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        mMockLooper.dispatchAll();
406ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen
4079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId1);
4089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId2);
40922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
410ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
411956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
412956f54b391677d78379729dd14518edddf3c7660Etan Cohen
41312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
4144375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * Validate that when the HAL doesn't respond we get a TIMEOUT (which
4154375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * results in a failure response) at which point we can process additional
4164375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * commands. Steps: (1) connect, (2) publish - timeout, (3) publish +
4174375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     * success.
4184375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen     */
4194375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    @Test
4204375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    public void testHalNoResponseTimeout() throws Exception {
4214375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final int clientId = 12341;
4227cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
423ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
424ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
4254375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
4264375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        final PublishConfig publishConfig = new PublishConfig.Builder().build();
4274375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
428c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
429c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
430c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
4314375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
4324375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
4334375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
434b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
435b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
436e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
437e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
438e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
439b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
4404375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (1) connect (successfully)
441f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
4424375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
4434375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
444db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
4454375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
4464375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
447b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
4484375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
4494375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (2) publish + timeout
4504375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
4514375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
4524375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).publish(anyShort(), eq(0), eq(publishConfig));
453c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        assertTrue(mAlarmManager.dispatch(WifiAwareStateManager.HAL_COMMAND_TIMEOUT_TAG));
4544375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
455db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
4564375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        validateInternalNoSessions(clientId);
4574375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
4584375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        // (3) publish + success
4594375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
4604375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
4614375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
4624375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, 9999);
4634375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        mMockLooper.dispatchAll();
4644375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
4654375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
466ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
4674375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    }
4684375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen
4694375ab0647dd81529c5e247cfaa3c1ffdbd8d6cdEtan Cohen    /**
4705254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * Validates publish flow: (1) initial publish (2) fail informed by notification, (3) fail due
4715254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * to immediate HAL failure. Expected: get a failure callback.
47212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
473956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
47412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishFail() throws Exception {
475c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
4767cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
477ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
478ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
479db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonFail = NanStatusType.INTERNAL_FAILURE;
480956f54b391677d78379729dd14518edddf3c7660Etan Cohen
4819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
48212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
483956f54b391677d78379729dd14518edddf3c7660Etan Cohen
484c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
485c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
486c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
487956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
4889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
489956f54b391677d78379729dd14518edddf3c7660Etan Cohen
490b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
491b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
492e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
493e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
494e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
495b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
4969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
497f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
4989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
4999864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
500db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
5019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
5029864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
503b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
504956f54b391677d78379729dd14518edddf3c7660Etan Cohen
50512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
5069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
507956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
5088f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
509956f54b391677d78379729dd14518edddf3c7660Etan Cohen
5105254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (2) publish failure callback (i.e. firmware tried and failed)
5119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
512956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
5139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
5149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalNoSessions(clientId);
515956f54b391677d78379729dd14518edddf3c7660Etan Cohen
5165254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (3) publish and get immediate failure (i.e. HAL failed)
5179fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.publish(anyShort(), anyInt(), any())).thenReturn(false);
5185254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
5195254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
5205254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
5215254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
5225254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
5235254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
5245254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        validateInternalNoSessions(clientId);
5255254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
5269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
52712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
52812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
52912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
53012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validates the publish flow: (1) initial publish (2) success (3)
53112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
53212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (6) update session attempt. Expected: session ID callback + session
5339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * cleaned-up.
53412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
53512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
53612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishSuccessTerminated() throws Exception {
53712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
5387cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
539ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
540ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
541db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonTerminate = NanStatusType.SUCCESS;
54212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
54312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
5449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
54512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
54612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
547c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
548c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
549c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
55012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
55112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
5529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
55312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
554b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
555b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
556e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
557e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
558e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
559b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
5609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
561f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
5629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
564db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
5659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
5669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
567b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
56812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
56912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
5709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
571956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
5728f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
573956f54b391677d78379729dd14518edddf3c7660Etan Cohen
57412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) publish success
5759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
57622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
5779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
57812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
57912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) publish termination (from firmware - not app!)
5809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(publishId, reasonTerminate, true);
5819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
5839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
58412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) app update session (race condition: app didn't get termination
58512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // yet)
58612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
5879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
58912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) app terminates session
59012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.terminateSession(clientId, sessionId.getValue());
5919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
5929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
59312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) app updates session (app already knows that terminated - will get
59412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // a local FAIL).
59512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
596956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
597956f54b391677d78379729dd14518edddf3c7660Etan Cohen
59812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
59912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
60112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
60212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
60312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
6045254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * Validate the publish flow: (1) initial publish + (2) success + (3) update + (4) update
6055254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * fails (callback from firmware) + (5) update + (6). Expected: session is still alive after
6065254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * update failure so second update succeeds (no callbacks) + (7) update + immediate failure from
6075254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * HAL.
60812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
60912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
61012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testPublishUpdateFail() throws Exception {
61112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
6127cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
613ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
614ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
61512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
616db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonFail = NanStatusType.INTERNAL_FAILURE;
61712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
61912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
620956f54b391677d78379729dd14518edddf3c7660Etan Cohen
621c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
622c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
623c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.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();
630e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
631e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
632e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
633b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
6349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
635f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
6369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
638db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
6399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
6409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
641b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
64212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
64312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial publish
6449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
645956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
6468f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
647956f54b391677d78379729dd14518edddf3c7660Etan Cohen
64812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) publish success
6499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
650956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
6519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
65212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
65312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) update publish
65412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
65512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
65612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
6578f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                eq(publishConfig));
65812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
65912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) update fails
6609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
6619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
6629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
66312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
66412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) another update publish
66512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
66612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
66712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
66812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                eq(publishConfig));
66912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
67012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) update succeeds
6719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
67212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
6739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
67412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
6755254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (7) another update + immediate failure
6769fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.publish(anyShort(), anyInt(), any())).thenReturn(false);
6775254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
6785254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
6795254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
6805254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
6815254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                eq(publishConfig));
6825254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
6835254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
684ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
68512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
68612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
68712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
68812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate race condition: publish pending but session terminated (due to
68912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * disconnect - can't terminate such a session directly from app). Need to
69012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * make sure that once publish succeeds (failure isn't a problem) the
69112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * session is immediately terminated since no-one is listening for it.
69212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
69312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
69412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testDisconnectWhilePublishPending() throws Exception {
69512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
6967cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
697ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
698ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
69912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 15;
70012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
70212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
70312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
704c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
705c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
706c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
70712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
7089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
70912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
710b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
711b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
712e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
713e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
714e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
715b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
7169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
717f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
7189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
720db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
7219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
72212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
723b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
72412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) initial publish
7269864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
7279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
72812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
72912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) disconnect (but doesn't get executed until get response for
7319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // publish command)
7329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
73312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
73412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
7359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) publish success
7369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
7379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
738ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
73912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).stopPublish(transactionId.capture(), eq(publishId));
7409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
7419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
7429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId);
7439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
744ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
745956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
746956f54b391677d78379729dd14518edddf3c7660Etan Cohen
74712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
7485254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * Validates subscribe flow: (1) initial subscribe (2) fail (callback from firmware), (3) fail
7495254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * due to immeidate HAL failure. Expected: get a failure callback.
75012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
751956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
75212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeFail() throws Exception {
753c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
7547cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
755ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
756ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
757db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonFail = NanStatusType.INTERNAL_FAILURE;
758956f54b391677d78379729dd14518edddf3c7660Etan Cohen
7599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
76012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
761956f54b391677d78379729dd14518edddf3c7660Etan Cohen
762c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
763c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
764c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
765956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
7669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
767956f54b391677d78379729dd14518edddf3c7660Etan Cohen
768b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
769b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
770e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
771e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
772e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
773b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
7749864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
775f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
7769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
7779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
778db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
7799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
7809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
781b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
782956f54b391677d78379729dd14518edddf3c7660Etan Cohen
78312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
7849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
785956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
7868f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
787956f54b391677d78379729dd14518edddf3c7660Etan Cohen
78812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe failure
7899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
790956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
7919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
7929864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalNoSessions(clientId);
793956f54b391677d78379729dd14518edddf3c7660Etan Cohen
7945254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (3) subscribe and get immediate failure (i.e. HAL failed)
7959fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.subscribe(anyShort(), anyInt(), any()))
7965254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                .thenReturn(false);
7975254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
7985254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
7995254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
8005254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
8015254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
8025254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
8035254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        validateInternalNoSessions(clientId);
8045254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
8059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
80612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
80712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
80812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
80912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validates the subscribe flow: (1) initial subscribe (2) success (3)
81012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
81112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (6) update session attempt. Expected: session ID callback + session
8129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * cleaned-up
81312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
81412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
81512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeSuccessTerminated() throws Exception {
81612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
8177cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
818ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
819ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
820db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonTerminate = NanStatusType.SUCCESS;
82112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
82212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
8239864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
82412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
82512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
826c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
827c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
828c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
82912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
83012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
8319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
83212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
833b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
834b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
835e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
836e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
837e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
838b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
8399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
840f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
8419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
843db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
8449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
8459864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
846b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
84712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
84812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
8499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
850956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8518f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
852956f54b391677d78379729dd14518edddf3c7660Etan Cohen
85312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe success
8549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
855956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
8569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
85712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
85812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) subscribe termination (from firmware - not app!)
8599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(subscribeId, reasonTerminate, false);
8609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
8629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
86312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) app update session (race condition: app didn't get termination
86412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // yet)
86512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
8669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
8679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
86812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) app terminates session
86912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.terminateSession(clientId, sessionId.getValue());
87022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
87122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
8729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (6) app updates session
8739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
8749864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
87512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
87612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
87712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
8789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
87912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
88012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
88112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
8825254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * Validate the subscribe flow: (1) initial subscribe + (2) success + (3) update + (4) update
8835254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * fails (callback from firmware) + (5) update + (6). Expected: session is still alive after
8845254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * update failure so second update succeeds (no callbacks). + (7) update + immediate failure
8855254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen     * from HAL.
88612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
88712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
88812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testSubscribeUpdateFail() throws Exception {
88912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
8907cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
891ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
892ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
89312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
894db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonFail = NanStatusType.INTERNAL_FAILURE;
89512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
8969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
89712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
89812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
899c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
900c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
901c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
90212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
90312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
9049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
90512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
906b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
907b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
908e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
909e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
910e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
911b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
9129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
913f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
9149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
916db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
9179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
9189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
919b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
920956f54b391677d78379729dd14518edddf3c7660Etan Cohen
92112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (1) initial subscribe
9229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
923956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
9248f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
925956f54b391677d78379729dd14518edddf3c7660Etan Cohen
92612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (2) subscribe success
9279864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
928956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
9299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
93012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
93112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (3) update subscribe
93212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
93312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
93412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
9358f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                eq(subscribeConfig));
93612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
93712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (4) update fails
9389864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
9399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
94112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
94212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (5) another update subscribe
94312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
94412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
94512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
94612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                eq(subscribeConfig));
94712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
94812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        // (6) update succeeds
9499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
95012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
9519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
95212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
9535254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        // (7) another update + immediate failure
9549fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.subscribe(anyShort(), anyInt(), any()))
9555254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                .thenReturn(false);
9565254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
9575254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
9585254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        mMockLooper.dispatchAll();
9595254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
9605254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen                eq(subscribeConfig));
9615254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
9625254a256676974e9db86fcb86b2f41af7d4a59f5Etan Cohen
963ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
964956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
965956f54b391677d78379729dd14518edddf3c7660Etan Cohen
96612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
96712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate race condition: subscribe pending but session terminated (due to
96812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * disconnect - can't terminate such a session directly from app). Need to
96912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * make sure that once subscribe succeeds (failure isn't a problem) the
97012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * session is immediately terminated since no-one is listening for it.
97112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
97212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    @Test
97312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    public void testDisconnectWhileSubscribePending() throws Exception {
97412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int clientId = 2005;
9757cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
976ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
977ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
97812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 15;
97912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
9809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
98112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
98212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
983c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
984c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
985c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
98612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
9879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
98812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
989b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
990b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
991e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
992e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
993e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
994b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
9959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
996f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
9979864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
9989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
999db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
10009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
100112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
1002b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
100312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
10049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) initial subscribe
10059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
10069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
100712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
100812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
10099864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) disconnect (but doesn't get executed until get response for
10109864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // subscribe command)
10119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
10129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
101312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
10149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) subscribe success
10159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
101612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
1017ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
10189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).stopSubscribe((short) 0, subscribeId);
10199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
102012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
10219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId);
10229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
1023ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
102412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
102512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
102612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
1027e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen     * Validate (1) subscribe (success), (2) match (i.e. discovery), (3) message reception,
1028e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen     * (4) message transmission failed (after ok queuing), (5) message transmission success.
102912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
1030956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
1031956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void testMatchAndMessages() throws Exception {
1032c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 1005;
10337cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1034ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1035ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
1036956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String serviceName = "some-service-name";
1037956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String ssi = "some much longer and more arbitrary data";
1038db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reasonFail = NanStatusType.INTERNAL_FAILURE;
1039956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int subscribeId = 15;
1040956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int requestorId = 22;
1041956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
1042956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerSsi = "some peer ssi data";
1043956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
1044956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final String peerMsg = "some message from peer";
10452e09c384f5ce86061b115f20fe3ca75a175d87f0Etan Cohen        final int messageId = 6948;
10461bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int messageId2 = 6949;
1047956f54b391677d78379729dd14518edddf3c7660Etan Cohen
10489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
10498f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
10508098201f7351a41f55524fbe09fb4332d34f7094Etan Cohen                .setServiceSpecificInfo(ssi.getBytes())
10518f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setSubscribeType(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE)
10520b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen                .build();
1053956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1054c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1055c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1056c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
1057956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
105812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
10599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
1060956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1061b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1062b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1063e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1064e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1065e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1066b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
10679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (0) connect
1068f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
1069956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
10709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
1071db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
10729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
10739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1074b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
1075956f54b391677d78379729dd14518edddf3c7660Etan Cohen
10769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) subscribe
10779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
10789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
10798f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
10809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
10819864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
10829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
1083956f54b391677d78379729dd14518edddf3c7660Etan Cohen
10849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) match
10859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
108680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1087956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
10889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
108980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1090956f54b391677d78379729dd14518edddf3c7660Etan Cohen
10919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message Rx
109280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(subscribeId, requestorId, peerMac, peerMsg.getBytes());
10939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
109480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(requestorId, peerMsg.getBytes());
1095956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1096e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        // (4) message Tx successful queuing
109780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), messageId, 0);
1098956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
1099956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
110080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
11011bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        short tid1 = transactionId.getValue();
11021bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid1);
1103956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
11041bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1105e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        // (5) message Tx successful queuing
110680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), messageId2,
110780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                0);
11081bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11091bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
111080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId2));
11111bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        short tid2 = transactionId.getValue();
11121bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid2);
11131bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11141bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1115e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        // (4) and (5) final Tx results (on-air results)
11161bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendFailNotification(tid1, reasonFail);
11171bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(tid2);
11181bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
11191bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId, reasonFail);
11201bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId2);
1121e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
1122e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId2);
1123956f54b391677d78379729dd14518edddf3c7660Etan Cohen
1124ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
1125956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
1126956f54b391677d78379729dd14518edddf3c7660Etan Cohen
112722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
112822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: in a single publish session interact with multiple peers
112922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * (different MAC addresses).
113022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
113122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
113222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testMultipleMessageSources() throws Exception {
1133c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 300;
11347cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1135ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1136ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
113722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 7;
113822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 7;
113922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 0;
114022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
114122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 88;
114222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId1 = 568;
114322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId2 = 873;
114422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMac1 = HexEncoding.decode("000102030405".toCharArray(), false);
114522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMac2 = HexEncoding.decode("060708090A0B".toCharArray(), false);
114622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer1 = "hey from 000102...";
114722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer2 = "hey from 0607...";
114822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer1 = "hey there 000102...";
114922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer2 = "hey there 0506...";
115022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId1 = 546;
115122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId2 = 9654;
1152db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        final int reason = NanStatusType.INTERNAL_FAILURE;
115322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
115422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
115522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
115622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
11578f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
11588f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
115922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
116022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
116112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1162c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1163c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1164c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
1165676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1166676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
1167b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1168b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1169e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1170e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1171e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1172b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
11739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
1174f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
117522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
11769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1177db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
11789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
11799864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1180b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
118122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
11829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
11839864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
11849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
11858f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
11869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
118712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
118812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
118912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
11909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message received from peers 1 & 2
119180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(publishId, peerId1, peerMac1, msgFromPeer1.getBytes());
119280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(publishId, peerId2, peerMac2, msgFromPeer2.getBytes());
119322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
119480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId1, msgFromPeer1.getBytes());
119580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId2, msgFromPeer2.getBytes());
11969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
11979864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) sending messages back to same peers: one Tx fails, other succeeds
11989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId2, msgToPeer2.getBytes(),
119980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                msgToPeerId2, 0);
12009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
120122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId2),
120280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(peerMac2), eq(msgToPeer2.getBytes()), eq(msgToPeerId2));
12039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        short transactionIdVal = transactionId.getValue();
12041bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
12051bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionIdVal);
12069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
12079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId1, msgToPeer1.getBytes(),
120880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                msgToPeerId1, 0);
12099864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
12109864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
121122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId1),
121280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(peerMac1), eq(msgToPeer1.getBytes()), eq(msgToPeerId1));
12139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        transactionIdVal = transactionId.getValue();
12141bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
12151bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendFailNotification(transactionIdVal, reason);
121622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
1217676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(msgToPeerId1, reason);
1218e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(msgToPeerId1);
1219e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(msgToPeerId2);
12209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
1221ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
122222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
122322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
122422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
122522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: interact with a peer which changed its identity (MAC address)
122622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * but which keeps its requestor instance ID. Should be transparent.
122722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
122822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
122922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testMessageWhilePeerChangesIdentity() throws Exception {
1230c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 300;
12317cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1232ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1233ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
123422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 7;
123522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 7;
123622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 0;
123722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
123822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 88;
123922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int peerId = 568;
124022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMacOrig = HexEncoding.decode("000102030405".toCharArray(), false);
124122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final byte[] peerMacLater = HexEncoding.decode("060708090A0B".toCharArray(), false);
124222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer1 = "hey from 000102...";
124322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgFromPeer2 = "hey from 0607...";
124422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer1 = "hey there 000102...";
124522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String msgToPeer2 = "hey there 0506...";
124622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId1 = 546;
124722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int msgToPeerId2 = 9654;
124822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
124922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
125022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
12518f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
12528f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
125322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
125422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
125512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
1256c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1257c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1258c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
1259676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
1260676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
1261b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1262b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1263e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1264e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1265e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1266b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
12679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
1268f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
126922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
12709864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1271db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
12729864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
12739864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1274b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
127522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
12769864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
12779864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
12789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
12798f06198cafd0e52aebe2f050af0c1a3533270888Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
12809864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
128122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
128212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
128312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
12849864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) message received & responded to
128580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(publishId, peerId, peerMacOrig, msgFromPeer1.getBytes());
128612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer1.getBytes(),
128780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                msgToPeerId1, 0);
128812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
128980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer1.getBytes());
129022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
129180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(peerMacOrig), eq(msgToPeer1.getBytes()), eq(msgToPeerId1));
12921bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
12931bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
12949864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
12959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId1);
1296e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(msgToPeerId1);
129722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
12989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) message received with same peer ID but different MAC
129980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(publishId, peerId, peerMacLater,
130080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                msgFromPeer2.getBytes());
130112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer2.getBytes(),
130280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                msgToPeerId2, 0);
130322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
130480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer2.getBytes());
130522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
130680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(peerMacLater), eq(msgToPeer2.getBytes()), eq(msgToPeerId2));
13071bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
13081bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
130922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
1310676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
1311e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(msgToPeerId2);
131222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
1313ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
131422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
131522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
13169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
13179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validate that get failure (with correct code) when trying to send a
13189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * message to an invalid peer ID.
13199864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
1320956f54b391677d78379729dd14518edddf3c7660Etan Cohen    @Test
1321cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    public void testSendMessageToInvalidPeerId() throws Exception {
1322cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int clientId = 1005;
13237cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1324ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1325ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
1326cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String ssi = "some much longer and more arbitrary data";
1327cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int subscribeId = 15;
1328cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int requestorId = 22;
1329cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
1330cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String peerSsi = "some peer ssi data";
1331cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final String peerMatchFilter = "filter binary array represented as string";
1332cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        final int messageId = 6948;
1333cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
13349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
1335cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
1336cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
1337c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1338c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1339c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
1340cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
134112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
13429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
1343cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
1344b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1345b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1346e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1347e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1348e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1349b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
13509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
1351f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
13529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
13539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1354db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
13559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1356cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
1357b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
1358cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
13599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) subscribe & match
13609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
13619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
1362cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
13639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
13649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
136580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1366cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
13679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
13689864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
136980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1370cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
13719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) send message to invalid peer ID
137212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId + 5, ssi.getBytes(),
137380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                messageId, 0);
1374cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen        mMockLooper.dispatchAll();
13759864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
1376db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanStatusType.INTERNAL_FAILURE);
1377e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
1378cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
1379ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
1380cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    }
1381cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen
13829864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
138326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * Validate that on send message errors are handled correctly: immediate send error, queue fail
138426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * error (not queue full), and timeout. Behavior: correct callback is dispatched and a later
138526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * firmware notification is ignored. Intersperse with one successfull transmission.
13861bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen     */
13871bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    @Test
138826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    public void testSendMessageErrorsImmediateQueueTimeout() throws Exception {
13891bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int clientId = 1005;
13907cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1391ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1392ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
13931bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String ssi = "some much longer and more arbitrary data";
13941bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int subscribeId = 15;
13951bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int requestorId = 22;
13961bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
13971bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String peerSsi = "some peer ssi data";
13981bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
13991bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        final int messageId = 6948;
14001bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
14011bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
14021bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
14031bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1404c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1405c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1406c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
14071bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
14081bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
14091bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
14101bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1411b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1412b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1413e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1414e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1415e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1416b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
14171bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (1) connect
1418f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
14191bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14201bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1421db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
14221bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
14231bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
1424b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
14251bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
14261bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        // (2) subscribe & match
14271bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
14281bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14291bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
14301bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
14311bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
143280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
14331bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14341bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
14351bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
143680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
14371bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
1438e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        // (3) send 2 messages and enqueue successfully
14391bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
144080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                messageId, 0);
14411bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14421bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
144380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
1444e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        short transactionId1 = transactionId.getValue();
1445e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId1);
1446e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1447e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1448e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
144980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                messageId + 1, 0);
1450e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1451e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
145280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 1));
1453e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        short transactionId2 = transactionId.getValue();
1454e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId2);
14551bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14561bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
145726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (4) send a message and get a queueing failure (not queue full)
145826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), messageId + 2,
145926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                0);
146026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
146126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
146226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 2));
146326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        short transactionId3 = transactionId.getValue();
146426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendQueuedFailResponse(transactionId3, NanStatusType.INTERNAL_FAILURE);
146526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
146626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId + 2,
146726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                NanStatusType.INTERNAL_FAILURE);
146826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId + 2);
146926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
147026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (5) send a message and get an immediate failure (configure first)
14719fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(),
14729fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any(), anyInt())).thenReturn(false);
147326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
147426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), messageId + 3,
147526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                0);
147626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
147726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
147826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 3));
147926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        short transactionId4 = transactionId.getValue();
148026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId + 3,
148126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                NanStatusType.INTERNAL_FAILURE);
148226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId + 3);
148326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
148426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (6) message send timeout
1485c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        assertTrue(mAlarmManager.dispatch(WifiAwareStateManager.HAL_SEND_MESSAGE_TIMEOUT_TAG));
14861bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
14871bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
1488db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanStatusType.INTERNAL_FAILURE);
1489e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
14901bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
149126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (7) firmware response (unlikely - but good to check)
1492e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onMessageSendSuccessNotification(transactionId1);
1493e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onMessageSendSuccessNotification(transactionId2);
149426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
149526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // bogus: these didn't even go to firmware or weren't queued
149626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId3);
149726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendFailNotification(transactionId4, NanStatusType.INTERNAL_FAILURE);
14981bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mMockLooper.dispatchAll();
1499e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId + 1);
1500e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1501e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId + 1);
15021bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
15031bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
15041da4332949ad1053078053097bfc59a72653f477Etan Cohen    }
15051da4332949ad1053078053097bfc59a72653f477Etan Cohen
15061da4332949ad1053078053097bfc59a72653f477Etan Cohen    /**
15071da4332949ad1053078053097bfc59a72653f477Etan Cohen     * Validate that when sending a message with a retry count the message is retried the specified
15081da4332949ad1053078053097bfc59a72653f477Etan Cohen     * number of times. Scenario ending with success.
15091da4332949ad1053078053097bfc59a72653f477Etan Cohen     */
15101da4332949ad1053078053097bfc59a72653f477Etan Cohen    @Test
15111da4332949ad1053078053097bfc59a72653f477Etan Cohen    public void testSendMessageRetransmitSuccess() throws Exception {
15121da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int clientId = 1005;
15137cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1514ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1515ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
15161da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String ssi = "some much longer and more arbitrary data";
15171da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int subscribeId = 15;
15181da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int requestorId = 22;
15191da4332949ad1053078053097bfc59a72653f477Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
15201da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerSsi = "some peer ssi data";
15211da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
15221da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int messageId = 6948;
15231da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int retryCount = 3;
15241da4332949ad1053078053097bfc59a72653f477Etan Cohen
15251da4332949ad1053078053097bfc59a72653f477Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
15261da4332949ad1053078053097bfc59a72653f477Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
15271da4332949ad1053078053097bfc59a72653f477Etan Cohen
1528c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1529c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1530c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
15311da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
15321da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
15331da4332949ad1053078053097bfc59a72653f477Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
15341da4332949ad1053078053097bfc59a72653f477Etan Cohen
1535b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1536b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1537e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1538e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1539e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1540b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
15411da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (1) connect
1542f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
15431da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15441da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1545db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
15461da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
15471da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
1548b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
15491da4332949ad1053078053097bfc59a72653f477Etan Cohen
15501da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (2) subscribe & match
15511da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
15521da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15531da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
15541da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
15551da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
155680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
15571da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15581da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
15591da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
156080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
15611da4332949ad1053078053097bfc59a72653f477Etan Cohen
15621da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (3) send message and enqueue successfully
15631da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
156480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                messageId, retryCount);
15651da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15661da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
156780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
15681da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
15691da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15701da4332949ad1053078053097bfc59a72653f477Etan Cohen
15711da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (4) loop and fail until reach retryCount
15721da4332949ad1053078053097bfc59a72653f477Etan Cohen        for (int i = 0; i < retryCount; ++i) {
1573db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusType.NO_OTA_ACK);
15741da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
15751da4332949ad1053078053097bfc59a72653f477Etan Cohen            inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
157680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                    eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
15771da4332949ad1053078053097bfc59a72653f477Etan Cohen            mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
15781da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
15791da4332949ad1053078053097bfc59a72653f477Etan Cohen        }
15801da4332949ad1053078053097bfc59a72653f477Etan Cohen
15811da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (5) succeed on last retry
15821da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendSuccessNotification(transactionId.getValue());
15831da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
15841da4332949ad1053078053097bfc59a72653f477Etan Cohen
15851da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
1586e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
15871da4332949ad1053078053097bfc59a72653f477Etan Cohen
15881da4332949ad1053078053097bfc59a72653f477Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
15891da4332949ad1053078053097bfc59a72653f477Etan Cohen    }
15901da4332949ad1053078053097bfc59a72653f477Etan Cohen
15911da4332949ad1053078053097bfc59a72653f477Etan Cohen    /**
15921da4332949ad1053078053097bfc59a72653f477Etan Cohen     * Validate that when sending a message with a retry count the message is retried the specified
15931da4332949ad1053078053097bfc59a72653f477Etan Cohen     * number of times. Scenario ending with failure.
15941da4332949ad1053078053097bfc59a72653f477Etan Cohen     */
15951da4332949ad1053078053097bfc59a72653f477Etan Cohen    @Test
15961da4332949ad1053078053097bfc59a72653f477Etan Cohen    public void testSendMessageRetransmitFail() throws Exception {
15971da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int clientId = 1005;
15987cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
1599ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1600ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
16011da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String ssi = "some much longer and more arbitrary data";
16021da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int subscribeId = 15;
16031da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int requestorId = 22;
16041da4332949ad1053078053097bfc59a72653f477Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
16051da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerSsi = "some peer ssi data";
16061da4332949ad1053078053097bfc59a72653f477Etan Cohen        final String peerMatchFilter = "filter binary array represented as string";
16071da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int messageId = 6948;
16081da4332949ad1053078053097bfc59a72653f477Etan Cohen        final int retryCount = 3;
16091da4332949ad1053078053097bfc59a72653f477Etan Cohen
16101da4332949ad1053078053097bfc59a72653f477Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
16111da4332949ad1053078053097bfc59a72653f477Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
16121da4332949ad1053078053097bfc59a72653f477Etan Cohen
1613c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1614c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1615c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
16161da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
16171da4332949ad1053078053097bfc59a72653f477Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
16181da4332949ad1053078053097bfc59a72653f477Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
16191da4332949ad1053078053097bfc59a72653f477Etan Cohen
1620b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
1621b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
1622e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
1623e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1624e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1625b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
16261da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (1) connect
1627f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
16281da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
16291da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
1630db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
16311da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
16321da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
1633b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
16341da4332949ad1053078053097bfc59a72653f477Etan Cohen
16351da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (2) subscribe & match
16361da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
16371da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
16381da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
16391da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
16401da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
164180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
16421da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
16431da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
16441da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
164580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
16461da4332949ad1053078053097bfc59a72653f477Etan Cohen
16471da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (3) send message and enqueue successfully
164880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), messageId,
164980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                retryCount);
16501da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
16511da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
165280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
16531da4332949ad1053078053097bfc59a72653f477Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
16541da4332949ad1053078053097bfc59a72653f477Etan Cohen        mMockLooper.dispatchAll();
16551da4332949ad1053078053097bfc59a72653f477Etan Cohen
16561da4332949ad1053078053097bfc59a72653f477Etan Cohen        // (4) loop and fail until reach retryCount+1
16571da4332949ad1053078053097bfc59a72653f477Etan Cohen        for (int i = 0; i < retryCount + 1; ++i) {
1658db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusType.NO_OTA_ACK);
16591da4332949ad1053078053097bfc59a72653f477Etan Cohen            mMockLooper.dispatchAll();
16601da4332949ad1053078053097bfc59a72653f477Etan Cohen
16611da4332949ad1053078053097bfc59a72653f477Etan Cohen            if (i != retryCount) {
16621da4332949ad1053078053097bfc59a72653f477Etan Cohen                inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
166380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                        eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
16641da4332949ad1053078053097bfc59a72653f477Etan Cohen                mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
16651da4332949ad1053078053097bfc59a72653f477Etan Cohen                mMockLooper.dispatchAll();
16661da4332949ad1053078053097bfc59a72653f477Etan Cohen            }
16671da4332949ad1053078053097bfc59a72653f477Etan Cohen        }
16681da4332949ad1053078053097bfc59a72653f477Etan Cohen
16691da4332949ad1053078053097bfc59a72653f477Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
1670db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanStatusType.NO_OTA_ACK);
1671e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
16721da4332949ad1053078053097bfc59a72653f477Etan Cohen
16731da4332949ad1053078053097bfc59a72653f477Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
16741bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    }
16751bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
167680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen    /**
167726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * Validate that the host-side message queue functions. Tests the perfect case of queue always
167826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * succeeds and all messages are received on first attempt.
167980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen     */
168080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen    @Test
168126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    public void testSendMessageQueueSequence() throws Exception {
168280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final int clientId = 1005;
168380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final int uid = 1000;
1684ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1685ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
168680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final String serviceName = "some-service-name";
168780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final int subscribeId = 15;
168880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final int requestorId = 22;
168980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
169026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int messageIdBase = 6948;
169126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int numberOfMessages = 30;
169226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int queueDepth = 6;
169380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
169480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
169580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
169626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                .build();
169780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
1698c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1699c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1700c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
170180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
170280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
170326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ArgumentCaptor<Integer> messageIdCaptor = ArgumentCaptor.forClass(Integer.class);
170480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
170580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
170680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.enableUsage();
170780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
170880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
170980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
171080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
171180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
171280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        // (0) connect
1713f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
171480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
171580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
1716db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
171780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
171880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
1719b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
172080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
172180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        // (1) subscribe
172280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
172380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
172480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
172580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
172680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
172780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
172880a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
172980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        // (2) match
173026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, null, null);
173180a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mMockLooper.dispatchAll();
173226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, null, null);
173380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
173426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (3) transmit messages
173526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        SendMessageQueueModelAnswer answerObj = new SendMessageQueueModelAnswer(queueDepth,
173626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                null, null, null);
17379fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(),
17389fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any(), anyInt())).thenAnswer(answerObj);
173980a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
174026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        int remainingMessages = numberOfMessages;
174126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        for (int i = 0; i < numberOfMessages; ++i) {
174226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mDut.sendMessage(clientId, sessionId.getValue(), requestorId, null, messageIdBase + i,
174326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    0);
174426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mMockLooper.dispatchAll();
174526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // at 1/2 interval have the system simulate transmitting a queued message over-the-air
174626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (i % 2 == 1) {
174726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                assertTrue(answerObj.process());
174826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                remainingMessages--;
174926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                mMockLooper.dispatchAll();
175026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            }
175126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
175226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        for (int i = 0; i < remainingMessages; ++i) {
175326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            assertTrue(answerObj.process());
175426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mMockLooper.dispatchAll();
175526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
175626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        assertEquals("queue empty", 0, answerObj.queueSize());
17573796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen
175826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback, times(numberOfMessages)).onMessageSendSuccess(
175926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                messageIdCaptor.capture());
176026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        for (int i = 0; i < numberOfMessages; ++i) {
176126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            assertEquals("message ID: " + i, (long) messageIdBase + i,
176226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    (long) messageIdCaptor.getAllValues().get(i));
176326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
176426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
176526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback);
176626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    }
176726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
176826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    /**
176926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * Validate that the host-side message queue functions. A combination of imperfect conditions:
177026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * - Failure to queue: synchronous firmware error
177126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * - Failure to queue: asyncronous firmware error
177226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * - Failure to transmit: OTA (which will be retried)
177326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * - Failure to transmit: other
177426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     */
177526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    @Test
177626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    public void testSendMessageQueueSequenceImperfect() throws Exception {
177726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int clientId = 1005;
177826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int uid = 1000;
177926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int pid = 2000;
178026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final String callingPackage = "com.google.somePackage";
178126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final String serviceName = "some-service-name";
178226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int subscribeId = 15;
178326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int requestorId = 22;
178426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
178526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int messageIdBase = 6948;
178626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int numberOfMessages = 300;
178726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int queueDepth = 6;
178826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final int retransmitCount = 3; // not the maximum
178926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
179026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
179126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
179226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                .build();
179326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
179426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
179526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
179626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
179726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
179826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
179926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ArgumentCaptor<Integer> messageIdCaptor = ArgumentCaptor.forClass(Integer.class);
180026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
180126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
180226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.enableUsage();
18033796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen        mMockLooper.dispatchAll();
180426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
180526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
18063796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen        mMockLooper.dispatchAll();
18073796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen
180826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (0) connect
180926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
18103796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen        mMockLooper.dispatchAll();
181126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
181226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(configRequest), eq(false), eq(true));
181326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
181426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
181526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
18163796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen
181726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (1) subscribe
181826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
18193796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen        mMockLooper.dispatchAll();
182026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
182126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
18223796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen        mMockLooper.dispatchAll();
182326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
18243796e636715ec00ac4548c4c09b0290ed09c8ba7Etan Cohen
182526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (2) match
182626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, null, null);
182726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
182826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, null, null);
182926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
183026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (3) transmit messages: configure a mix of failures/success
183126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        Set<Integer> failQueueCommandImmediately = new HashSet<>();
183226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        Set<Integer> failQueueCommandLater = new HashSet<>();
183326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        Map<Integer, Integer> numberOfRetries = new HashMap<>();
183426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
183526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        int numOfSuccesses = 0;
183626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        int numOfFailuresInternalFailure = 0;
183726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        int numOfFailuresNoOta = 0;
183826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        for (int i = 0; i < numberOfMessages; ++i) {
183926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // random results:
184026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // - 0-50: success
184126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // - 51-60: retransmit value (which will fail for >5)
184226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // - 61-70: fail queue later
184326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // - 71-80: fail queue immediately
184426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            // - 81-90: fail retransmit with non-OTA failure
184526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            int random = mRandomNg.nextInt(90);
184626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (random <= 50) {
184726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numberOfRetries.put(messageIdBase + i, 0);
184826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numOfSuccesses++;
184926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } else if (random <= 60) {
185026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numberOfRetries.put(messageIdBase + i, random - 51);
185126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                if (random - 51 > retransmitCount) {
185226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    numOfFailuresNoOta++;
185326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                } else {
185426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    numOfSuccesses++;
185526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                }
185626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } else if (random <= 70) {
185726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                failQueueCommandLater.add(messageIdBase + i);
185826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numOfFailuresInternalFailure++;
185926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } else if (random <= 80) {
186026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                failQueueCommandImmediately.add(messageIdBase + i);
186126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numOfFailuresInternalFailure++;
186226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } else {
186326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numberOfRetries.put(messageIdBase + i, -1);
186426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                numOfFailuresInternalFailure++;
186526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            }
186626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
186780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
186826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        Log.v("WifiAwareStateManagerTest",
186926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                "failQueueCommandImmediately=" + failQueueCommandImmediately
187026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        + ", failQueueCommandLater=" + failQueueCommandLater + ", numberOfRetries="
187126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        + numberOfRetries + ", numOfSuccesses=" + numOfSuccesses
187226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        + ", numOfFailuresInternalFailure=" + numOfFailuresInternalFailure
187326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        + ", numOfFailuresNoOta=" + numOfFailuresNoOta);
187480a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen
187526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        SendMessageQueueModelAnswer answerObj = new SendMessageQueueModelAnswer(queueDepth,
187626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                failQueueCommandImmediately, failQueueCommandLater, numberOfRetries);
18779fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(),
18789fdded9b33d8b519b713d682ca63dffc8a2191bcEtan Cohen                any(), anyInt())).thenAnswer(answerObj);
1879e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
188026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        for (int i = 0; i < numberOfMessages; ++i) {
188126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mDut.sendMessage(clientId, sessionId.getValue(), requestorId, null, messageIdBase + i,
188226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    retransmitCount);
188326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mMockLooper.dispatchAll();
188426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
1885e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
188626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        while (answerObj.queueSize() != 0) {
188726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            assertTrue(answerObj.process());
188826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mMockLooper.dispatchAll();
188926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
1890e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
189126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        verify(mockSessionCallback, times(numOfSuccesses)).onMessageSendSuccess(anyInt());
189226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        verify(mockSessionCallback, times(numOfFailuresInternalFailure)).onMessageSendFail(anyInt(),
189326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(NanStatusType.INTERNAL_FAILURE));
189426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        verify(mockSessionCallback, times(numOfFailuresNoOta)).onMessageSendFail(anyInt(),
189526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(NanStatusType.NO_OTA_ACK));
1896e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
189726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback);
1898e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    }
1899e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1900e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    /**
190126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen     * Validate that can send empty message successfully: null, byte[0], ""
1902e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen     */
190326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    @Test
190426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    public void testSendEmptyMessages() throws Exception {
1905e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final int clientId = 1005;
1906e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final int uid = 1000;
1907ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
1908ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
190926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        final String serviceName = "some-service-name";
1910e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final String ssi = "some much longer and more arbitrary data";
1911e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final int subscribeId = 15;
1912e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final int requestorId = 22;
1913e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
1914e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final String peerSsi = "some peer ssi data";
1915e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final String peerMatchFilter = "filter binary array represented as string";
1916e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        final int messageId = 6948;
1917e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1918e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
191926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
192026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                .setServiceSpecificInfo(ssi.getBytes())
192126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                .setSubscribeType(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE)
19220b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen                .build();
1923e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1924c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
1925c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
1926c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
1927e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
1928e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
192926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        ArgumentCaptor<byte[]> byteArrayCaptor = ArgumentCaptor.forClass(byte[].class);
193026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
1931e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
1932e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.enableUsage();
1933e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
193426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
193526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
1936e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1937e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
193826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (0) connect
1939f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
1940e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
194126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
194226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(configRequest), eq(false), eq(true));
1943e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
1944e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
194526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
1946e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
194726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (1) subscribe
1948e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
1949e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
195026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
1951e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
195226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
195326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
195426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
195526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (2) match
1956e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
195780a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1958e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
195926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
196080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
1961e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
196226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (3) message null Tx successful queuing
196326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, null, messageId, 0);
196426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
196526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
196626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(requestorId), eq(peerMac), isNull(byte[].class), eq(messageId));
196726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        short tid = transactionId.getValue();
196826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid);
1969e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
1970e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
197126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (4) final Tx results (on-air results)
197226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendSuccessNotification(tid);
197326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
197426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
197526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
1976e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
197726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (5) message byte[0] Tx successful queuing
197826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, new byte[0], messageId, 0);
197926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
198026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
198126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(requestorId), eq(peerMac), eq(new byte[0]), eq(messageId));
198226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        tid = transactionId.getValue();
198326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid);
198426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
1985e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
198626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (6) final Tx results (on-air results)
198726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendSuccessNotification(tid);
198826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
198926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
199026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
199126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
199226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (7) message "" Tx successful queuing
199326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, "".getBytes(), messageId, 0);
199426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
199526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
199626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                eq(requestorId), eq(peerMac), byteArrayCaptor.capture(), eq(messageId));
199726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        collector.checkThat("Empty message contents", "",
199826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                equalTo(new String(byteArrayCaptor.getValue())));
199926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        tid = transactionId.getValue();
200026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(tid);
200126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
200226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
200326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // (8) final Tx results (on-air results)
200426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mDut.onMessageSendSuccessNotification(tid);
200526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        mMockLooper.dispatchAll();
200626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
200726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        validateInternalSendMessageQueuesCleanedUp(messageId);
20081da4332949ad1053078053097bfc59a72653f477Etan Cohen
20091da4332949ad1053078053097bfc59a72653f477Etan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
20101bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    }
20111bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen
201226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen    private class SendMessageQueueModelAnswer extends MockAnswerUtil.AnswerWithArguments {
201326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final int mMaxQueueDepth;
2014e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
201526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // keyed by message ID
201626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final Set<Integer> mFailQueueCommandImmediately; // return a false
201726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final Set<Integer> mFailQueueCommandLater; // return an error != TX_QUEUE_FULL
2018e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
201926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // # of times to return NO_OTA_ACK before returning SUCCESS. So a 0 means success on first
202026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // try, a very large number means - never succeed (since max retry is 5).
202126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        // a -1 impiles a non-OTA failure: on first attempt
202226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final Map<Integer, Integer> mRetryLimit;
2023e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
202426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final LinkedList<Short> mQueue = new LinkedList<>(); // transaction ID (tid)
202526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final Map<Short, Integer> mMessageIdsByTid = new HashMap<>(); // tid -> message ID
202626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        private final Map<Integer, Integer> mTriesUsedByMid = new HashMap<>(); // mid -> # of retx
2027e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
202826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        SendMessageQueueModelAnswer(int maxQueueDepth, Set<Integer> failQueueCommandImmediately,
202926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                Set<Integer> failQueueCommandLater, Map<Integer, Integer> numberOfRetries) {
203026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mMaxQueueDepth = maxQueueDepth;
203126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mFailQueueCommandImmediately = failQueueCommandImmediately;
203226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mFailQueueCommandLater = failQueueCommandLater;
203326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            mRetryLimit = numberOfRetries;
2034e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
203526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (mRetryLimit != null) {
203626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                for (int mid : mRetryLimit.keySet()) {
203726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mTriesUsedByMid.put(mid, 0);
203826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                }
203926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            }
2040e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        }
2041e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2042e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        public boolean answer(short transactionId, int pubSubId, int requestorInstanceId,
204380a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                byte[] dest, byte[] message, int messageId) throws Exception {
204426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (mFailQueueCommandImmediately != null && mFailQueueCommandImmediately.contains(
204526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    messageId)) {
204626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                return false;
2047e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            }
2048e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
204926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (mFailQueueCommandLater != null && mFailQueueCommandLater.contains(messageId)) {
205026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                mDut.onMessageSendQueuedFailResponse(transactionId, NanStatusType.INTERNAL_FAILURE);
2051e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            } else {
205226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                if (mQueue.size() <= mMaxQueueDepth) {
205326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mQueue.addLast(transactionId);
205426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mMessageIdsByTid.put(transactionId, messageId);
205526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mDut.onMessageSendQueuedSuccessResponse(transactionId);
205626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                } else {
205726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mDut.onMessageSendQueuedFailResponse(transactionId,
205826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                            NanStatusType.FOLLOWUP_TX_QUEUE_FULL);
205926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                }
206026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            }
206126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
206226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            return true;
206326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
206426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
206526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        /**
206626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen         * Processes the first message in the queue: i.e. responds as if sent over-the-air
206726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen         * (successfully or failed)
206826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen         */
206926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        boolean process() {
207026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (mQueue.size() == 0) {
207126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                return false;
2072e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            }
207326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            short tid = mQueue.poll();
207426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            int mid = mMessageIdsByTid.get(tid);
2075e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
207626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            if (mRetryLimit != null && mRetryLimit.containsKey(mid)) {
207726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                int numRetries = mRetryLimit.get(mid);
207826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                if (numRetries == -1) {
207926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mDut.onMessageSendFailNotification(tid, NanStatusType.INTERNAL_FAILURE);
2080e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                } else {
208126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    int currentRetries = mTriesUsedByMid.get(mid);
208226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    if (currentRetries > numRetries) {
208326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        return false; // shouldn't be retrying!?
208426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    } else if (currentRetries == numRetries) {
208526f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        mDut.onMessageSendSuccessNotification(tid);
208626f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    } else {
208726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                        mDut.onMessageSendFailNotification(tid, NanStatusType.NO_OTA_ACK);
208826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    }
208926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                    mTriesUsedByMid.put(mid, currentRetries + 1);
2090e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                }
209126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            } else {
209226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen                mDut.onMessageSendSuccessNotification(tid);
2093e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            }
209426f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
2095e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            return true;
2096e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        }
209726f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen
209826f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        /**
209926f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen         * Returns the number of elements in the queue.
210026f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen         */
210126f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        int queueSize() {
210226f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen            return mQueue.size();
210326f57d4921a2390f90d4bf474cb76ec3761d6c69Etan Cohen        }
2104e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    }
2105e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
21061bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen    /**
21077335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     * Validate that start ranging function fills-in correct MAC addresses for peer IDs and
21087335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     * passed along to RTT module.
21097335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen     */
21107335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    @Test
21117335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    public void testStartRanging() throws Exception {
21127335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int clientId = 1005;
21137cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2114ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2115ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
21167335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int subscribeId = 15;
21177335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int requestorId = 22;
21187335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
21197335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final String peerSsi = "some peer ssi data";
21207335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final String peerMatchFilter = "filter binary array represented as string";
21217335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final int rangingId = 18423;
21227335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        final RttManager.RttParams[] params = new RttManager.RttParams[2];
21237335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[0] = new RttManager.RttParams();
21247335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[0].bssid = Integer.toString(requestorId);
21257335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[1] = new RttManager.RttParams();
21267335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        params[1].bssid = Integer.toString(requestorId + 5);
21277335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21287335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
21297335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
21307335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
2131c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2132c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2133c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
21347335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21357335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
21367335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
2137c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        ArgumentCaptor<WifiAwareClientState> clientCaptor =
2138c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                ArgumentCaptor.forClass(WifiAwareClientState.class);
21397335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        ArgumentCaptor<RttManager.RttParams[]> rttParamsCaptor =
21407335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                ArgumentCaptor.forClass(RttManager.RttParams[].class);
21417335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21427335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative,
2143c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                mMockAwareRttStateManager);
21447335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
2145b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2146b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2147e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2148e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2149e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2150b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
21517335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (1) connect
2152f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
21537335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
21547335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2155db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
21567335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
21577335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
2158b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
21597335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21607335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (2) subscribe & match
21617335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
21627335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
21637335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
21647335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
21657335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
216680a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
21677335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
21687335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
21697335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
217080a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen                peerMatchFilter.getBytes());
21717335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21727335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        // (3) start ranging: pass along a valid peer ID and an invalid one
21737335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mDut.startRanging(clientId, sessionId.getValue(), params, rangingId);
21747335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        mMockLooper.dispatchAll();
2175c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        inOrder.verify(mMockAwareRttStateManager).startRanging(eq(rangingId),
2176c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                clientCaptor.capture(), rttParamsCaptor.capture());
21777335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        collector.checkThat("RttParams[0].bssid", "06:07:08:09:0A:0B",
21787335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen                equalTo(rttParamsCaptor.getValue()[0].bssid));
21797335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        collector.checkThat("RttParams[1].bssid", "", equalTo(rttParamsCaptor.getValue()[1].bssid));
21807335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21817335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative,
2182c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                mMockAwareRttStateManager);
21837335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    }
21847335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
21857335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen    /**
21869864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Test sequence of configuration: (1) config1, (2) config2 - incompatible,
21879864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * (3) config3 - compatible with config1 (requiring upgrade), (4) disconnect
21889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * config3 (should get a downgrade), (5) disconnect config1 (should get a
21899864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * disable).
21909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
2191cc0da689f0cf3e5b5e3a0b43a8d571fd1911efecEtan Cohen    @Test
2192956f54b391677d78379729dd14518edddf3c7660Etan Cohen    public void testConfigs() throws Exception {
2193c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId1 = 9999;
219449a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int clientId2 = 1001;
219549a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int clientId3 = 1005;
21967cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2197ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2198ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
2199956f54b391677d78379729dd14518edddf3c7660Etan Cohen        final int masterPref1 = 111;
220049a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int masterPref3 = 115;
220149a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int dwInterval1Band24 = 2;
220249a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int dwInterval3Band24 = 1;
220349a847941e08faec5901d4824040a522b773ef83Etan Cohen        final int dwInterval3Band5 = 0;
2204956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2205956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2206956f54b391677d78379729dd14518edddf3c7660Etan Cohen        ArgumentCaptor<ConfigRequest> crCapture = ArgumentCaptor.forClass(ConfigRequest.class);
2207956f54b391677d78379729dd14518edddf3c7660Etan Cohen
220849a847941e08faec5901d4824040a522b773ef83Etan Cohen        ConfigRequest configRequest1 = new ConfigRequest.Builder()
220949a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setClusterLow(5).setClusterHigh(100)
221049a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setMasterPreference(masterPref1)
221149a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwInterval1Band24)
221249a847941e08faec5901d4824040a522b773ef83Etan Cohen                .build();
221349a847941e08faec5901d4824040a522b773ef83Etan Cohen
221449a847941e08faec5901d4824040a522b773ef83Etan Cohen        ConfigRequest configRequest2 = new ConfigRequest.Builder()
221549a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setSupport5gBand(true) // compatible
221649a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setClusterLow(7).setClusterHigh(155) // incompatible!
221749a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setMasterPreference(0) // compatible
221849a847941e08faec5901d4824040a522b773ef83Etan Cohen                .build();
2219956f54b391677d78379729dd14518edddf3c7660Etan Cohen
222049a847941e08faec5901d4824040a522b773ef83Etan Cohen        ConfigRequest configRequest3  = new ConfigRequest.Builder()
222149a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setSupport5gBand(true) // compatible (will use true)
222249a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setClusterLow(5).setClusterHigh(100) // identical (hence compatible)
222349a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setMasterPreference(masterPref3) // compatible (will use max)
222449a847941e08faec5901d4824040a522b773ef83Etan Cohen                // compatible: will use min
222549a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwInterval3Band24)
222649a847941e08faec5901d4824040a522b773ef83Etan Cohen                // compatible: will use interval3 since interval1 not init
222749a847941e08faec5901d4824040a522b773ef83Etan Cohen                .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwInterval3Band5)
222849a847941e08faec5901d4824040a522b773ef83Etan Cohen                .build();
2229956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2230c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
2231c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
2232c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback3 = mock(IWifiAwareEventCallback.class);
2233956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2234676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback1, mockCallback2, mockCallback3);
2235956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2236b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2237b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2238e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2239e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2240e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2241b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
22429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) config1 (valid)
2243f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId1, uid, pid, callingPackage, mockCallback1, configRequest1, false);
2244956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
2245956f54b391677d78379729dd14518edddf3c7660Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
2246db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                crCapture.capture(), eq(false), eq(true));
22479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("merge: stage 1", crCapture.getValue(), equalTo(configRequest1));
22489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
2249956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
2250b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback1).onConnectSuccess(clientId1);
2251956f54b391677d78379729dd14518edddf3c7660Etan Cohen
22529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) config2 (incompatible with config1)
2253f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId2, uid, pid, callingPackage, mockCallback2, configRequest2, false);
2254956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
2255db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        inOrder.verify(mockCallback2).onConnectFail(NanStatusType.INTERNAL_FAILURE);
22569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId2);
2257956f54b391677d78379729dd14518edddf3c7660Etan Cohen
225849a847941e08faec5901d4824040a522b773ef83Etan Cohen        // (3) config3 (compatible with config1)
225949a847941e08faec5901d4824040a522b773ef83Etan Cohen        mDut.connect(clientId3, uid, pid, callingPackage, mockCallback3, configRequest3, true);
226049a847941e08faec5901d4824040a522b773ef83Etan Cohen        mMockLooper.dispatchAll();
226149a847941e08faec5901d4824040a522b773ef83Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
226249a847941e08faec5901d4824040a522b773ef83Etan Cohen                crCapture.capture(), eq(true), eq(false));
226349a847941e08faec5901d4824040a522b773ef83Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
226449a847941e08faec5901d4824040a522b773ef83Etan Cohen        mMockLooper.dispatchAll();
226549a847941e08faec5901d4824040a522b773ef83Etan Cohen        inOrder.verify(mockCallback3).onConnectSuccess(clientId3);
226649a847941e08faec5901d4824040a522b773ef83Etan Cohen
226749a847941e08faec5901d4824040a522b773ef83Etan Cohen        collector.checkThat("support 5g: or", true, equalTo(crCapture.getValue().mSupport5gBand));
226849a847941e08faec5901d4824040a522b773ef83Etan Cohen        collector.checkThat("master preference: max", Math.max(masterPref1, masterPref3),
226949a847941e08faec5901d4824040a522b773ef83Etan Cohen                equalTo(crCapture.getValue().mMasterPreference));
227049a847941e08faec5901d4824040a522b773ef83Etan Cohen        collector.checkThat("dw interval on 2.4: ~min",
227149a847941e08faec5901d4824040a522b773ef83Etan Cohen                Math.min(dwInterval1Band24, dwInterval3Band24),
227249a847941e08faec5901d4824040a522b773ef83Etan Cohen                equalTo(crCapture.getValue().mDiscoveryWindowInterval[ConfigRequest
227349a847941e08faec5901d4824040a522b773ef83Etan Cohen                        .NAN_BAND_24GHZ]));
227449a847941e08faec5901d4824040a522b773ef83Etan Cohen        collector.checkThat("dw interval on 5: ~min", dwInterval3Band5,
227549a847941e08faec5901d4824040a522b773ef83Etan Cohen                equalTo(crCapture.getValue().mDiscoveryWindowInterval[ConfigRequest
227649a847941e08faec5901d4824040a522b773ef83Etan Cohen                        .NAN_BAND_5GHZ]));
227749a847941e08faec5901d4824040a522b773ef83Etan Cohen
227849a847941e08faec5901d4824040a522b773ef83Etan Cohen        // (4) disconnect config3: downgrade to config1
227949a847941e08faec5901d4824040a522b773ef83Etan Cohen        mDut.disconnect(clientId3);
228049a847941e08faec5901d4824040a522b773ef83Etan Cohen        mMockLooper.dispatchAll();
228149a847941e08faec5901d4824040a522b773ef83Etan Cohen        validateInternalClientInfoCleanedUp(clientId3);
228249a847941e08faec5901d4824040a522b773ef83Etan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
228349a847941e08faec5901d4824040a522b773ef83Etan Cohen                crCapture.capture(), eq(false), eq(false));
228449a847941e08faec5901d4824040a522b773ef83Etan Cohen
228549a847941e08faec5901d4824040a522b773ef83Etan Cohen        collector.checkThat("configRequest1", configRequest1, equalTo(crCapture.getValue()));
228649a847941e08faec5901d4824040a522b773ef83Etan Cohen
228749a847941e08faec5901d4824040a522b773ef83Etan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
228849a847941e08faec5901d4824040a522b773ef83Etan Cohen        mMockLooper.dispatchAll();
228949a847941e08faec5901d4824040a522b773ef83Etan Cohen
22909864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (5) disconnect config1: disable
2291c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        mDut.disconnect(clientId1);
2292956f54b391677d78379729dd14518edddf3c7660Etan Cohen        mMockLooper.dispatchAll();
22939864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        validateInternalClientInfoCleanedUp(clientId1);
22949864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
2295956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2296ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback1, mockCallback2, mockCallback3);
2297956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
2298956f54b391677d78379729dd14518edddf3c7660Etan Cohen
229922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
230022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Summary: disconnect a client while there are pending transactions.
230122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
230222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
230322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    public void testDisconnectWithPendingTransactions() throws Exception {
2304c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        final int clientId = 125;
23057cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2306ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2307ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
230822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterLow = 5;
230922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int clusterHigh = 100;
231022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int masterPref = 111;
231122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String serviceName = "some-service-name";
231222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final String ssi = "some much longer and more arbitrary data";
231322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        final int publishId = 22;
231422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
231522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
231622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
231722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
23188098201f7351a41f55524fbe09fb4332d34f7094Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
23198098201f7351a41f55524fbe09fb4332d34f7094Etan Cohen                serviceName).setServiceSpecificInfo(ssi.getBytes()).setPublishType(
23200b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen                PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
232122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
232222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2323c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2324c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2325c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
2326676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
2327676d8394860aa8fb0ed856f41bbd0bbe2c4727fcEtan Cohen
2328b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2329b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2330e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2331e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2332e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2333b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
23349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
2335f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
23369864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
23379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2338db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
23399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
23409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2341b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
23429864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
23439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish (no response yet)
234412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
234522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
23469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
234722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
23489864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) disconnect (but doesn't get executed until get a RESPONSE to the
23499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // previous publish)
23509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.disconnect(clientId);
23519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
235222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
23539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (4) get successful response to the publish
23549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
23559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2356ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
23579864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).stopPublish((short) 0, publishId);
23589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).disable((short) 0);
235922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2360c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        validateInternalClientInfoCleanedUp(clientId);
236122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
23629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (5) trying to publish on the same client: NOP
23639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
236422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
236522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
23669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (6) got some callback on original publishId - should be ignored
2367cecebde8ef6445860c111f252c9dbb02e15e42d7Etan Cohen        mDut.onSessionTerminatedNotification(publishId, 0, true);
236822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        mMockLooper.dispatchAll();
236922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2370ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
237122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
237222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
237322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
23744f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that an unknown transaction (i.e. a callback from HAL with an
23754f1887493430b6b61126f233f3de54201b363145Etan Cohen     * unknown type) is simply ignored - but also cleans up its state.
23764f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
23774f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
23784f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testUnknownTransactionType() throws Exception {
23794f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 129;
23807cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2381ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2382ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
23834f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clusterLow = 15;
23844f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clusterHigh = 192;
23854f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int masterPref = 234;
23864f1887493430b6b61126f233f3de54201b363145Etan Cohen        final String serviceName = "some-service-name";
23874f1887493430b6b61126f233f3de54201b363145Etan Cohen        final String ssi = "some much longer and more arbitrary data";
23884f1887493430b6b61126f233f3de54201b363145Etan Cohen
23894f1887493430b6b61126f233f3de54201b363145Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
23904f1887493430b6b61126f233f3de54201b363145Etan Cohen                .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
23914f1887493430b6b61126f233f3de54201b363145Etan Cohen
23928098201f7351a41f55524fbe09fb4332d34f7094Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
23938098201f7351a41f55524fbe09fb4332d34f7094Etan Cohen                serviceName).setServiceSpecificInfo(ssi.getBytes()).setPublishType(
23940b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen                PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
23954f1887493430b6b61126f233f3de54201b363145Etan Cohen
23964f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2397c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2398c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockPublishSessionCallback = mock(
2399c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
24004f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockPublishSessionCallback);
24014f1887493430b6b61126f233f3de54201b363145Etan Cohen
2402b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2403b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2404e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2405e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2406e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2407b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
24089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
2409f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
24109864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
24119864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2412db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
24139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
24144f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
2415b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
24164f1887493430b6b61126f233f3de54201b363145Etan Cohen
24179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish - no response
24189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockPublishSessionCallback);
24194f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
24209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
24214f1887493430b6b61126f233f3de54201b363145Etan Cohen
2422ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockPublishSessionCallback);
24234f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
24244f1887493430b6b61126f233f3de54201b363145Etan Cohen
24254f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
24264f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that a NoOp transaction (i.e. a callback from HAL which doesn't
24274f1887493430b6b61126f233f3de54201b363145Etan Cohen     * require any action except clearing up state) actually cleans up its state
24284f1887493430b6b61126f233f3de54201b363145Etan Cohen     * (and does nothing else).
24294f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
24304f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
24314f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testNoOpTransaction() throws Exception {
24324f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 1294;
24337cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2434ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2435ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
24364f1887493430b6b61126f233f3de54201b363145Etan Cohen
24379864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
24384f1887493430b6b61126f233f3de54201b363145Etan Cohen
24394f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2440c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2441c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2442c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
24434f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
24444f1887493430b6b61126f233f3de54201b363145Etan Cohen
2445b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2446b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2447e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2448e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2449e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2450b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
24519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect (no response)
2452f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
24534f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
24549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2455db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
24564f1887493430b6b61126f233f3de54201b363145Etan Cohen
2457ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
24584f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
24594f1887493430b6b61126f233f3de54201b363145Etan Cohen
24604f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
24614f1887493430b6b61126f233f3de54201b363145Etan Cohen     * Validate that getting callbacks from HAL with unknown (expired)
24624f1887493430b6b61126f233f3de54201b363145Etan Cohen     * transaction ID or invalid publish/subscribe ID session doesn't have any
24634f1887493430b6b61126f233f3de54201b363145Etan Cohen     * impact.
24644f1887493430b6b61126f233f3de54201b363145Etan Cohen     */
24654f1887493430b6b61126f233f3de54201b363145Etan Cohen    @Test
24664f1887493430b6b61126f233f3de54201b363145Etan Cohen    public void testInvalidCallbackIdParameters() throws Exception {
24679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int pubSubId = 1235;
24684f1887493430b6b61126f233f3de54201b363145Etan Cohen        final int clientId = 132;
24697cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2470ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2471ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
24724f1887493430b6b61126f233f3de54201b363145Etan Cohen
24734f1887493430b6b61126f233f3de54201b363145Etan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
24744f1887493430b6b61126f233f3de54201b363145Etan Cohen
24754f1887493430b6b61126f233f3de54201b363145Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
2476c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
24774f1887493430b6b61126f233f3de54201b363145Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback);
24784f1887493430b6b61126f233f3de54201b363145Etan Cohen
2479b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2480b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2481e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2482e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2483e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2484b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
24859864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect and succeed
2486f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
24874f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
24889864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2489db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
24904f1887493430b6b61126f233f3de54201b363145Etan Cohen        short transactionIdConfig = transactionId.getValue();
24919864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionIdConfig);
24924f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
2493b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
24944f1887493430b6b61126f233f3de54201b363145Etan Cohen
24959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) use the same transaction ID to send a bunch of other responses
24969864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionIdConfig);
24979864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigFailedResponse(transactionIdConfig, -1);
24989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionIdConfig, true, -1);
24991bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedSuccessResponse(transactionIdConfig);
25001bf97ad103217a2e18370c382fe30abd88716d53Etan Cohen        mDut.onMessageSendQueuedFailResponse(transactionIdConfig, -1);
25019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigFailResponse(transactionIdConfig, false, -1);
250280a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMatchNotification(-1, -1, new byte[0], new byte[0], new byte[0]);
25039864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(-1, -1, true);
25049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionTerminatedNotification(-1, -1, false);
250580a6988b532a1a63a164a6ff7f63ac88762bd633Etan Cohen        mDut.onMessageReceivedNotification(-1, -1, new byte[0], new byte[0]);
25069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionIdConfig, true, pubSubId);
25079864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionIdConfig, false, pubSubId);
25084f1887493430b6b61126f233f3de54201b363145Etan Cohen        mMockLooper.dispatchAll();
25094f1887493430b6b61126f233f3de54201b363145Etan Cohen
2510ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback);
25114f1887493430b6b61126f233f3de54201b363145Etan Cohen    }
25124f1887493430b6b61126f233f3de54201b363145Etan Cohen
25134f1887493430b6b61126f233f3de54201b363145Etan Cohen    /**
251412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Validate that trying to update-subscribe on a publish session fails.
2515e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     */
2516e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    @Test
2517e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    public void testSubscribeOnPublishSessionType() throws Exception {
2518e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        final int clientId = 188;
25197cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2520ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2521ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
252212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int publishId = 25;
2523e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
25249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
2525e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
2526e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
2527e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
2528e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
252912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
2530c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2531c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2532c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
2533e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
2534e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
2535b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2536b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2537e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2538e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2539e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2540b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
25419864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
2542f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
25439864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
25449864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
2545db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(false), eq(true));
25469864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
2547e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
2548b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
2549e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
25509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) publish
25519864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.publish(clientId, publishConfig, mockSessionCallback);
25529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2553e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
25549864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
255512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
255612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
255712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
25589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) update-subscribe -> failure
255912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
2560e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
2561db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
25629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
2563ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
2564e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    }
2565e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
2566e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    /**
2567e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     * Validate that trying to (re)subscribe on a publish session or (re)publish
2568e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     * on a subscribe session fails.
2569e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen     */
2570e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    @Test
2571e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    public void testPublishOnSubscribeSessionType() throws Exception {
2572e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        final int clientId = 188;
25737cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2574ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2575ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
257612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        final int subscribeId = 25;
2577e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
25789864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
2579e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
2580e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
2581e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
2582e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
258312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
2584c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2585c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2586c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
2587e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
2588e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
2589b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2590b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2591e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2592e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2593e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2594b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
25959864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
2596f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
2597e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
25989864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
2599db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
26009864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
26019864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2602b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
2603e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
26049864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (2) subscribe
26059864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
26069864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2607e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
26089864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
260912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mMockLooper.dispatchAll();
261012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
261112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
26129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (3) update-publish -> error
261312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
2614e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen        mMockLooper.dispatchAll();
2615db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
26169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
2617ebefdf6a93bb136f42cf60ada3b24c8eaf902b46Etan Cohen        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
2618e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen    }
2619e903e3cb1e7a41fa20306dc3bd1f3518c51a8a86Etan Cohen
26209864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
26219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Validate that the session ID increments monotonically
26229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
262322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    @Test
26249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    public void testSessionIdIncrement() throws Exception {
26259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        final int clientId = 188;
26267cde468702a73a2eafdb2b3aa08340a1cfbc749bEtan Cohen        final int uid = 1000;
2627ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final int pid = 2000;
2628ae719e944792a5bc36ec26230bee16f1415ce141Etan Cohen        final String callingPackage = "com.google.somePackage";
262922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        int loopCount = 100;
263022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
26319864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ConfigRequest configRequest = new ConfigRequest.Builder().build();
26329864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        PublishConfig publishConfig = new PublishConfig.Builder().build();
26339864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
26349864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
26359864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
2636c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
2637c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
2638c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                IWifiAwareDiscoverySessionCallback.class);
26399864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
26409864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
2641b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mDut.enableUsage();
2642b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen        mMockLooper.dispatchAll();
2643e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
2644e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
2645e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        mMockLooper.dispatchAll();
2646b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen
26479864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        // (1) connect
2648f7237ad859aa94bbb0ed4f5cb94ee4b9bfed4045Etan Cohen        mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
26499864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
26509864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
2651db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                eq(configRequest), eq(false), eq(true));
26529864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mDut.onConfigSuccessResponse(transactionId.getValue());
26539864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        mMockLooper.dispatchAll();
2654b42d3c062d8c542798f631c29275506c82e3bde3Etan Cohen        inOrder.verify(mockCallback).onConnectSuccess(clientId);
26559864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
26569864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        int prevId = 0;
265722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        for (int i = 0; i < loopCount; ++i) {
26589864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            // (2) publish
26599864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mDut.publish(clientId, publishConfig, mockSessionCallback);
26609864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mMockLooper.dispatchAll();
26619864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
26629864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
26639864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            // (3) publish-success
26649864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, i + 1);
26659864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            mMockLooper.dispatchAll();
26669864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
26679864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
266822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen            if (i != 0) {
26699864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                assertTrue("Session ID incrementing", sessionId.getValue() > prevId);
267022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen            }
26719864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen            prevId = sessionId.getValue();
267222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        }
267322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
267422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
267522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /*
2676c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen     * Tests of internal state of WifiAwareStateManager: very limited (not usually
267722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * a good idea). However, these test that the internal state is cleaned-up
267822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * appropriately. Alternatively would cause issues with memory leaks or
267922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * information leak between sessions.
268022b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
268122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
268222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    /**
268322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * Utility routine used to validate that the internal state is cleaned-up
268422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * after a client is disconnected. To be used in every test which terminates
268522b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     * a client.
268622b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     *
2687c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen     * @param clientId The ID of the client which should be deleted.
268822b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen     */
2689b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalClientInfoCleanedUp(int clientId) throws Exception {
2690c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        WifiAwareClientState client = getInternalClientState(mDut, clientId);
2691c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        collector.checkThat("Client record not cleared up for clientId=" + clientId, client,
2692c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen                nullValue());
269312a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
269412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
269512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    /**
269612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * Utility routine used to validate that the internal state is cleaned-up
269712a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * (deleted) after a session is terminated through API (not callback!). To
269812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * be used in every test which terminates a session.
269912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     *
270012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param clientId The ID of the client containing the session.
270112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     * @param sessionId The ID of the terminated session.
270212a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen     */
2703b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalSessionInfoCleanedUp(int clientId, int sessionId)
2704b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen            throws Exception {
2705c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        WifiAwareClientState client = getInternalClientState(mDut, clientId);
270612a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
2707c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        WifiAwareDiscoverySessionState session = getInternalSessionState(client, sessionId);
270812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        collector.checkThat("Client record not cleaned-up for sessionId=" + sessionId, session,
270912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen                nullValue());
27109864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    }
271112a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
27129864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen    /**
27139864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * Utility routine used to validate that the internal state is cleaned-up
27149864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * (deleted) correctly. Checks that a specific client has no sessions
27159864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * attached to it.
27169864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     *
27179864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     * @param clientId The ID of the client which we want to check.
27189864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen     */
2719b5ff110bcdf4a178e712184c06ff7c8b200e125dEtan Cohen    private void validateInternalNoSessions(int clientId) throws Exception {
2720c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        WifiAwareClientState client = getInternalClientState(mDut, clientId);
27219864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
27229864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
2723c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        Field field = WifiAwareClientState.class.getDeclaredField("mSessions");
27249864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        field.setAccessible(true);
27259864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        @SuppressWarnings("unchecked")
2726c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        SparseArray<WifiAwareDiscoverySessionState> sessions =
2727c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                (SparseArray<WifiAwareDiscoverySessionState>) field.get(client);
27289864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen
27299864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen        collector.checkThat("No sessions exist for clientId=" + clientId, sessions.size(),
27309864521b92325bad1d20510d99d4e967b6f3d4ebEtan Cohen                equalTo(0));
273122b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
273222b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
27331b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    /**
2734c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen     * Validates that the broadcast sent on Aware status change is correct.
27351b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     *
27361b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     * @param expectedEnabled The expected change status - i.e. are we expected
2737c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen     *            to announce that Aware is enabled (true) or disabled (false).
27381b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen     */
2739c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private void validateCorrectAwareStatusChangeBroadcast(InOrder inOrder,
2740c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen            boolean expectedEnabled) {
27411b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
27421b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
27431b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        inOrder.verify(mMockContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL));
27441b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
27451b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen        collector.checkThat("intent action", intent.getValue().getAction(),
2746c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                equalTo(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED));
27471b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen    }
27481b1f9b669d91b62c2b8c5572d4de87ef3fd79e42Etan Cohen
2749956f54b391677d78379729dd14518edddf3c7660Etan Cohen    /*
2750956f54b391677d78379729dd14518edddf3c7660Etan Cohen     * Utilities
2751956f54b391677d78379729dd14518edddf3c7660Etan Cohen     */
275249a847941e08faec5901d4824040a522b773ef83Etan Cohen    private void dumpDut(String prefix) {
275349a847941e08faec5901d4824040a522b773ef83Etan Cohen        StringWriter sw = new StringWriter();
275449a847941e08faec5901d4824040a522b773ef83Etan Cohen        mDut.dump(null, new PrintWriter(sw), null);
275549a847941e08faec5901d4824040a522b773ef83Etan Cohen        Log.e("WifiAwareStateManagerTest", prefix + sw.toString());
275649a847941e08faec5901d4824040a522b773ef83Etan Cohen    }
2757956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2758c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private static void installMocksInStateManager(WifiAwareStateManager awareStateManager,
2759c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen            WifiAwareRttStateManager mockRtt, WifiAwareDataPathStateManager mockDpMgr)
2760b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen            throws Exception {
2761c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        Field field = WifiAwareStateManager.class.getDeclaredField("mRtt");
27627335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen        field.setAccessible(true);
2763c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        field.set(awareStateManager, mockRtt);
27647335b7c3db2656c8379296593c7880ae56ccf9eaEtan Cohen
2765c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        field = WifiAwareStateManager.class.getDeclaredField("mDataPathMgr");
2766b9f574e46be8c535525c35dff5b8f987df5d5ed6Etan Cohen        field.setAccessible(true);
2767c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        field.set(awareStateManager, mockDpMgr);
2768956f54b391677d78379729dd14518edddf3c7660Etan Cohen    }
2769956f54b391677d78379729dd14518edddf3c7660Etan Cohen
2770c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private static WifiAwareClientState getInternalClientState(WifiAwareStateManager dut,
2771c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen            int clientId) throws Exception {
2772c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        Field field = WifiAwareStateManager.class.getDeclaredField("mClients");
277322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        field.setAccessible(true);
277422b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen        @SuppressWarnings("unchecked")
2775c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        SparseArray<WifiAwareClientState> clients = (SparseArray<WifiAwareClientState>) field.get(
2776c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                dut);
277722b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2778c9783c72ce84ea8cc42f2c407824113019e59b11Etan Cohen        return clients.get(clientId);
277922b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen    }
278012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
2781c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen    private static WifiAwareDiscoverySessionState getInternalSessionState(
2782c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen            WifiAwareClientState client, int sessionId) throws Exception {
2783c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        Field field = WifiAwareClientState.class.getDeclaredField("mSessions");
278412a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        field.setAccessible(true);
278512a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        @SuppressWarnings("unchecked")
2786c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        SparseArray<WifiAwareDiscoverySessionState> sessions =
2787c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                (SparseArray<WifiAwareDiscoverySessionState>) field.get(client);
278812a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen
278912a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen        return sessions.get(sessionId);
279012a73dbc70d547ea87048209fd84d9dace01be17Etan Cohen    }
2791e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2792e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    private void validateInternalSendMessageQueuesCleanedUp(int messageId) throws Exception {
2793c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        Field field = WifiAwareStateManager.class.getDeclaredField("mSm");
2794e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        field.setAccessible(true);
2795c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        WifiAwareStateManager.WifiAwareStateMachine sm =
2796c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen                (WifiAwareStateManager.WifiAwareStateMachine) field.get(mDut);
2797e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2798c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        field = WifiAwareStateManager.WifiAwareStateMachine.class.getDeclaredField(
2799e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                "mHostQueuedSendMessages");
2800e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        field.setAccessible(true);
2801e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        SparseArray<Message> hostQueuedSendMessages = (SparseArray<Message>) field.get(sm);
2802e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2803c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        field = WifiAwareStateManager.WifiAwareStateMachine.class.getDeclaredField(
2804e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                "mFwQueuedSendMessages");
2805e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        field.setAccessible(true);
2806e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        Map<Short, Message> fwQueuedSendMessages = (Map<Short, Message>) field.get(sm);
2807e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2808e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        for (int i = 0; i < hostQueuedSendMessages.size(); ++i) {
2809e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            Message msg = hostQueuedSendMessages.valueAt(i);
2810e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            if (msg.getData().getInt("message_id") == messageId) {
2811e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                collector.checkThat(
2812e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                        "Message not cleared-up from host queue. Message ID=" + messageId, msg,
2813e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                        nullValue());
2814e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            }
2815e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        }
2816e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2817e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        for (Message msg: fwQueuedSendMessages.values()) {
2818e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            if (msg.getData().getInt("message_id") == messageId) {
2819e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                collector.checkThat(
2820e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                        "Message not cleared-up from firmware queue. Message ID=" + messageId, msg,
2821e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen                        nullValue());
2822e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen            }
2823e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        }
2824e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    }
2825e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen
2826db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static Capabilities getCapabilities() {
2827db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        Capabilities cap = new Capabilities();
2828c29acea6ceda3aa4ee537c05ce7d05dac2655cf9Etan Cohen        cap.maxConcurrentAwareClusters = 1;
2829e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxPublishes = 2;
2830e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxSubscribes = 2;
2831e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxServiceNameLen = 255;
2832e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxMatchFilterLen = 255;
2833e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxTotalMatchFilterLen = 255;
2834e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxServiceSpecificInfoLen = 255;
283575bb2a1c3f5c513cde140a8cec417c67423465d2Etan Cohen        cap.maxExtendedServiceSpecificInfoLen = 255;
2836e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxNdiInterfaces = 1;
2837e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxNdpSessions = 1;
2838e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxAppInfoLen = 255;
2839e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        cap.maxQueuedTransmitMessages = 6;
2840e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen        return cap;
2841e27021e4c8c369554880ab522a1e27942b15687bEtan Cohen    }
2842956f54b391677d78379729dd14518edddf3c7660Etan Cohen}
284322b4156d2948e3108ae8439dc72f76fb97526aceEtan Cohen
2844