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