1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.uwb; 18 19 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 21 22 import static com.android.server.uwb.UwbSessionManager.SESSION_OPEN_RANGING; 23 import static com.android.server.uwb.UwbTestUtils.DATA_PAYLOAD; 24 import static com.android.server.uwb.UwbTestUtils.MAX_DATA_SIZE; 25 import static com.android.server.uwb.UwbTestUtils.PEER_BAD_MAC_ADDRESS; 26 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_MAC_ADDRESS; 27 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_MAC_ADDRESS_2; 28 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_MAC_ADDRESS_2_LONG; 29 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_MAC_ADDRESS_LONG; 30 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_SHORT_MAC_ADDRESS; 31 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_SHORT_MAC_ADDRESS_LONG; 32 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_SHORT_UWB_ADDRESS; 33 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_UWB_ADDRESS; 34 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_UWB_ADDRESS_2; 35 import static com.android.server.uwb.UwbTestUtils.PEER_SHORT_MAC_ADDRESS; 36 import static com.android.server.uwb.UwbTestUtils.PEER_SHORT_MAC_ADDRESS_LONG; 37 import static com.android.server.uwb.UwbTestUtils.PEER_SHORT_UWB_ADDRESS; 38 import static com.android.server.uwb.UwbTestUtils.PERSISTABLE_BUNDLE; 39 import static com.android.server.uwb.UwbTestUtils.RANGING_MEASUREMENT_TYPE_UNDEFINED; 40 import static com.android.server.uwb.UwbTestUtils.TEST_SESSION_ID; 41 import static com.android.server.uwb.UwbTestUtils.TEST_SESSION_ID_2; 42 import static com.android.server.uwb.UwbTestUtils.TEST_SESSION_TYPE; 43 import static com.android.server.uwb.data.UwbUciConstants.MAC_ADDRESSING_MODE_EXTENDED; 44 import static com.android.server.uwb.data.UwbUciConstants.MAC_ADDRESSING_MODE_SHORT; 45 import static com.android.server.uwb.data.UwbUciConstants.RANGING_DEVICE_ROLE_ADVERTISER; 46 import static com.android.server.uwb.data.UwbUciConstants.RANGING_DEVICE_ROLE_OBSERVER; 47 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_OWR_AOA; 48 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY; 49 import static com.android.server.uwb.data.UwbUciConstants.ROUND_USAGE_DS_TWR_DEFERRED_MODE; 50 import static com.android.server.uwb.data.UwbUciConstants.ROUND_USAGE_DS_TWR_NON_DEFERRED_MODE; 51 import static com.android.server.uwb.data.UwbUciConstants.ROUND_USAGE_OWR_AOA_MEASUREMENT; 52 import static com.android.server.uwb.data.UwbUciConstants.STATUS_CODE_DATA_TRANSFER_ERROR_DATA_TRANSFER; 53 import static com.android.server.uwb.data.UwbUciConstants.STATUS_CODE_DATA_TRANSFER_REPETITION_OK; 54 55 import static com.google.common.truth.Truth.assertThat; 56 import static com.google.uwb.support.fira.FiraParams.PROTOCOL_NAME; 57 import static com.google.uwb.support.fira.FiraParams.RangeDataNtfConfigCapabilityFlag.HAS_RANGE_DATA_NTF_CONFIG_DISABLE; 58 import static com.google.uwb.support.fira.FiraParams.RangeDataNtfConfigCapabilityFlag.HAS_RANGE_DATA_NTF_CONFIG_ENABLE; 59 import static com.google.uwb.support.fira.FiraParams.SESSION_TYPE_RANGING; 60 import static com.google.uwb.support.fira.FiraParams.STATUS_CODE_OK; 61 62 import static org.junit.Assert.assertNotNull; 63 import static org.junit.Assert.assertNull; 64 import static org.junit.Assert.assertThrows; 65 import static org.mockito.ArgumentMatchers.any; 66 import static org.mockito.ArgumentMatchers.anyByte; 67 import static org.mockito.ArgumentMatchers.anyInt; 68 import static org.mockito.ArgumentMatchers.anyLong; 69 import static org.mockito.ArgumentMatchers.anyString; 70 import static org.mockito.ArgumentMatchers.eq; 71 import static org.mockito.ArgumentMatchers.isA; 72 import static org.mockito.Mockito.atLeast; 73 import static org.mockito.Mockito.clearInvocations; 74 import static org.mockito.Mockito.doAnswer; 75 import static org.mockito.Mockito.doReturn; 76 import static org.mockito.Mockito.doThrow; 77 import static org.mockito.Mockito.mock; 78 import static org.mockito.Mockito.never; 79 import static org.mockito.Mockito.spy; 80 import static org.mockito.Mockito.times; 81 import static org.mockito.Mockito.verify; 82 import static org.mockito.Mockito.verifyNoMoreInteractions; 83 import static org.mockito.Mockito.verifyZeroInteractions; 84 import static org.mockito.Mockito.when; 85 86 import android.app.ActivityManager; 87 import android.app.ActivityManager.OnUidImportanceListener; 88 import android.app.AlarmManager; 89 import android.content.AttributionSource; 90 import android.os.IBinder; 91 import android.os.PersistableBundle; 92 import android.os.Process; 93 import android.os.RemoteException; 94 import android.os.test.TestLooper; 95 import android.uwb.IUwbAdapter; 96 import android.uwb.IUwbRangingCallbacks; 97 import android.uwb.RangingChangeReason; 98 import android.uwb.SessionHandle; 99 import android.uwb.StateChangeReason; 100 import android.uwb.UwbAddress; 101 import android.uwb.UwbOemExtensionCallbackListener; 102 103 import com.android.modules.utils.build.SdkLevel; 104 import com.android.server.uwb.UwbSessionManager.UwbSession; 105 import com.android.server.uwb.UwbSessionManager.WaitObj; 106 import com.android.server.uwb.advertisement.UwbAdvertiseManager; 107 import com.android.server.uwb.data.DtTagUpdateRangingRoundsStatus; 108 import com.android.server.uwb.data.UwbMulticastListUpdateStatus; 109 import com.android.server.uwb.data.UwbRangingData; 110 import com.android.server.uwb.data.UwbUciConstants; 111 import com.android.server.uwb.jni.NativeUwbManager; 112 import com.android.server.uwb.multchip.UwbMultichipData; 113 import com.android.server.uwb.params.TlvUtil; 114 115 import com.google.uwb.support.base.Params; 116 import com.google.uwb.support.ccc.CccOpenRangingParams; 117 import com.google.uwb.support.ccc.CccParams; 118 import com.google.uwb.support.ccc.CccPulseShapeCombo; 119 import com.google.uwb.support.ccc.CccSpecificationParams; 120 import com.google.uwb.support.ccc.CccStartRangingParams; 121 import com.google.uwb.support.dltdoa.DlTDoARangingRoundsUpdate; 122 import com.google.uwb.support.fira.FiraOpenSessionParams; 123 import com.google.uwb.support.fira.FiraParams; 124 import com.google.uwb.support.fira.FiraProtocolVersion; 125 import com.google.uwb.support.fira.FiraRangingReconfigureParams; 126 import com.google.uwb.support.fira.FiraSpecificationParams; 127 import com.google.uwb.support.generic.GenericSpecificationParams; 128 129 import org.junit.After; 130 import org.junit.Before; 131 import org.junit.Test; 132 import org.mockito.ArgumentCaptor; 133 import org.mockito.Captor; 134 import org.mockito.Mock; 135 import org.mockito.MockitoAnnotations; 136 137 import java.util.Arrays; 138 import java.util.Collections; 139 import java.util.EnumSet; 140 import java.util.List; 141 import java.util.Optional; 142 import java.util.Set; 143 import java.util.concurrent.ExecutionException; 144 import java.util.concurrent.ExecutorService; 145 import java.util.concurrent.FutureTask; 146 import java.util.concurrent.TimeoutException; 147 148 public class UwbSessionManagerTest { 149 private static final String TEST_CHIP_ID = "testChipId"; 150 private static final long MAX_FIRA_SESSION_NUM = 5; 151 private static final long MAX_CCC_SESSION_NUM = 1; 152 private static final int UID = 343453; 153 private static final String PACKAGE_NAME = "com.uwb.test"; 154 private static final int UID_2 = 67; 155 private static final String PACKAGE_NAME_2 = "com.android.uwb.2"; 156 private static final AttributionSource ATTRIBUTION_SOURCE = 157 new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build(); 158 private static final AttributionSource ATTRIBUTION_SOURCE_2 = 159 new AttributionSource.Builder(UID_2).setPackageName(PACKAGE_NAME_2).build(); 160 private static final SessionHandle SESSION_HANDLE = 161 new SessionHandle(TEST_SESSION_ID, ATTRIBUTION_SOURCE, 1); 162 private static final SessionHandle SESSION_HANDLE_2 = 163 new SessionHandle(TEST_SESSION_ID_2, ATTRIBUTION_SOURCE_2, 2); 164 private static final UwbAddress UWB_DEST_ADDRESS = 165 UwbAddress.fromBytes(new byte[] {(byte) 0x03, (byte) 0x04 }); 166 private static final UwbAddress UWB_DEST_ADDRESS_2 = 167 UwbAddress.fromBytes(new byte[] {(byte) 0x05, (byte) 0x06 }); 168 private static final UwbAddress UWB_DEST_ADDRESS_3 = 169 UwbAddress.fromBytes(new byte[] {(byte) 0x07, (byte) 0x08 }); 170 private static final int TEST_RANGING_INTERVAL_MS = 200; 171 private static final byte DATA_SEQUENCE_NUM = 0; 172 private static final byte DATA_SEQUENCE_NUM_1 = 2; 173 174 private static final int SOURCE_END_POINT = 100; 175 private static final int DEST_END_POINT = 200; 176 private static final int HANDLE_ID = 12; 177 private static final int MAX_RX_DATA_PACKETS_TO_STORE = 10; 178 private static final int PID = Process.myPid(); 179 180 @Mock 181 private UwbConfigurationManager mUwbConfigurationManager; 182 @Mock 183 private NativeUwbManager mNativeUwbManager; 184 @Mock 185 private UwbMetrics mUwbMetrics; 186 @Mock 187 private UwbAdvertiseManager mUwbAdvertiseManager; 188 @Mock 189 private UwbSessionNotificationManager mUwbSessionNotificationManager; 190 @Mock 191 private UwbInjector mUwbInjector; 192 @Mock 193 private ExecutorService mExecutorService; 194 @Mock 195 private AlarmManager mAlarmManager; 196 @Mock 197 private ActivityManager mActivityManager; 198 @Mock 199 private UwbServiceCore mUwbServiceCore; 200 @Mock 201 private DeviceConfigFacade mDeviceConfigFacade; 202 @Mock 203 private CccSpecificationParams mCccSpecificationParams; 204 @Mock 205 private UwbMultichipData mUwbMultichipData; 206 private TestLooper mTestLooper = new TestLooper(); 207 private UwbSessionManager mUwbSessionManager; 208 @Captor 209 private ArgumentCaptor<OnUidImportanceListener> mOnUidImportanceListenerArgumentCaptor; 210 private GenericSpecificationParams.Builder mSpecificationParamsBuilder; 211 212 @Before setup()213 public void setup() throws ExecutionException, InterruptedException, TimeoutException { 214 MockitoAnnotations.initMocks(this); 215 when(mUwbInjector.isSystemApp(UID, PACKAGE_NAME)).thenReturn(true); 216 when(mUwbInjector.isForegroundAppOrService(UID, PACKAGE_NAME)).thenReturn(true); 217 when(mUwbInjector.getUwbServiceCore()).thenReturn(mUwbServiceCore); 218 when(mUwbInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); 219 when(mUwbInjector.getMultichipData()).thenReturn(mUwbMultichipData); 220 doAnswer(invocation -> { 221 FutureTask t = invocation.getArgument(0); 222 t.run(); 223 return t.get(); 224 }).when(mUwbInjector).runTaskOnSingleThreadExecutor(any(FutureTask.class), anyInt()); 225 mSpecificationParamsBuilder = new GenericSpecificationParams.Builder() 226 .setCccSpecificationParams(mCccSpecificationParams) 227 .setFiraSpecificationParams( 228 new FiraSpecificationParams.Builder() 229 .setSupportedChannels(List.of(9)) 230 .setRangeDataNtfConfigCapabilities( 231 EnumSet.of( 232 HAS_RANGE_DATA_NTF_CONFIG_DISABLE, 233 HAS_RANGE_DATA_NTF_CONFIG_ENABLE)) 234 .build()); 235 when(mUwbServiceCore.getCachedSpecificationParams(any())).thenReturn( 236 mSpecificationParamsBuilder.build()); 237 when(mCccSpecificationParams.getMaxRangingSessionNumber()).thenReturn( 238 (int) MAX_CCC_SESSION_NUM); 239 when(mUwbMultichipData.getDefaultChipId()).thenReturn("default"); 240 when(mDeviceConfigFacade.isBackgroundRangingEnabled()).thenReturn(false); 241 when(mDeviceConfigFacade.isRangingErrorStreakTimerEnabled()).thenReturn(true); 242 243 // TODO: Don't use spy. 244 mUwbSessionManager = spy(new UwbSessionManager( 245 mUwbConfigurationManager, 246 mNativeUwbManager, 247 mUwbMetrics, 248 mUwbAdvertiseManager, 249 mUwbSessionNotificationManager, 250 mUwbInjector, 251 mAlarmManager, 252 mActivityManager, 253 mTestLooper.getLooper())); 254 255 verify(mActivityManager).addOnUidImportanceListener( 256 mOnUidImportanceListenerArgumentCaptor.capture(), anyInt()); 257 } 258 259 /** 260 * Called after each test 261 */ 262 @After cleanup()263 public void cleanup() { } 264 265 @Test onDataReceived_extendedMacAddressFormat_owrAoA()266 public void onDataReceived_extendedMacAddressFormat_owrAoA() { 267 UwbSession mockUwbSession = mock(UwbSession.class); 268 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 269 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 270 doReturn(mockUwbSession) 271 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 272 273 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 274 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 275 DATA_PAYLOAD); 276 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 277 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 278 } 279 280 @Test onDataReceived_unsupportedMacAddressLength_owrAoa()281 public void onDataReceived_unsupportedMacAddressLength_owrAoa() { 282 UwbSession mockUwbSession = mock(UwbSession.class); 283 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 284 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 285 doReturn(mockUwbSession) 286 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 287 288 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 289 DATA_SEQUENCE_NUM, PEER_BAD_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 290 DATA_PAYLOAD); 291 verify(mockUwbSession, never()).addReceivedDataInfo( 292 isA(UwbSessionManager.ReceivedDataInfo.class)); 293 verify(mUwbMetrics, never()).logDataRx(eq(mockUwbSession), 294 eq(UwbUciConstants.STATUS_CODE_OK)); 295 } 296 297 @Test onDataReceived_shortMacAddressFormat_owrAoa()298 public void onDataReceived_shortMacAddressFormat_owrAoa() { 299 UwbSession mockUwbSession = mock(UwbSession.class); 300 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 301 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 302 doReturn(mockUwbSession) 303 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 304 305 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 306 DATA_SEQUENCE_NUM, PEER_EXTENDED_SHORT_MAC_ADDRESS, SOURCE_END_POINT, 307 DEST_END_POINT, DATA_PAYLOAD); 308 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 309 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 310 } 311 312 @Test onDataReceived_shortMacAddressFormat_dsTwr()313 public void onDataReceived_shortMacAddressFormat_dsTwr() { 314 UwbSession mockUwbSession = mock(UwbSession.class); 315 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 316 when(mockUwbSession.getRangingRoundUsage()).thenReturn( 317 ROUND_USAGE_DS_TWR_NON_DEFERRED_MODE); 318 doReturn(mockUwbSession) 319 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 320 321 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 322 DATA_SEQUENCE_NUM, PEER_EXTENDED_SHORT_MAC_ADDRESS, SOURCE_END_POINT, 323 DEST_END_POINT, DATA_PAYLOAD); 324 325 verify(mUwbSessionNotificationManager).onDataReceived( 326 isA(UwbSession.class), eq(PEER_EXTENDED_SHORT_UWB_ADDRESS), 327 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 328 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 329 verify(mockUwbSession, never()).addReceivedDataInfo( 330 isA(UwbSessionManager.ReceivedDataInfo.class)); 331 } 332 333 @Test onRangeDataNotificationReceivedWithValidUwbSession_twoWay()334 public void onRangeDataNotificationReceivedWithValidUwbSession_twoWay() { 335 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 336 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 337 UwbUciConstants.STATUS_CODE_OK); 338 UwbSession mockUwbSession = mock(UwbSession.class); 339 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 340 doReturn(mockUwbSession) 341 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 342 343 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 344 345 verify(mUwbSessionNotificationManager) 346 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 347 } 348 349 @Test onRangeDataNotificationReceivedWithInvalidSession_twoWay()350 public void onRangeDataNotificationReceivedWithInvalidSession_twoWay() { 351 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 352 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 353 UwbUciConstants.STATUS_CODE_OK); 354 doReturn(null) 355 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 356 357 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 358 359 verify(mUwbSessionNotificationManager, never()) 360 .onRangingResult(any(), eq(uwbRangingData)); 361 } 362 363 // Test scenario for receiving Application payload data followed by a RANGE_DATA_NTF with an 364 // OWR Aoa Measurement (such that the ExtendedMacAddress format is used for the remote device). 365 @Test onRangeDataNotificationReceived_owrAoa_success_extendedMacAddress()366 public void onRangeDataNotificationReceived_owrAoa_success_extendedMacAddress() 367 throws RemoteException { 368 UwbSession mockUwbSession = mock(UwbSession.class); 369 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 370 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 371 doReturn(mockUwbSession) 372 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 373 UwbOemExtensionCallbackListener mUwbOemExtensionCallbackListener = 374 mock(UwbOemExtensionCallbackListener.class); 375 when(mUwbServiceCore.isOemExtensionCbRegistered()).thenReturn(true); 376 when(mUwbServiceCore.getOemExtensionCallback()) 377 .thenReturn(mUwbOemExtensionCallbackListener); 378 when(mUwbOemExtensionCallbackListener.onCheckPointedTarget(any())).thenReturn(true); 379 380 // First call onDataReceived() to get the application payload data. 381 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 382 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 383 DATA_PAYLOAD); 384 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 385 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 386 387 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 388 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 389 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 390 UwbUciConstants.STATUS_CODE_OK); 391 Params firaParams = setupFiraParams( 392 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 393 when(mockUwbSession.getParams()).thenReturn(firaParams); 394 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(true); 395 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)) 396 .thenReturn(List.of(buildReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG))); 397 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 398 399 verify(mUwbSessionNotificationManager) 400 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 401 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 402 verify(mUwbSessionNotificationManager) 403 .onDataReceived(eq(mockUwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 404 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 405 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_EXTENDED_MAC_ADDRESS_LONG); 406 verify(mUwbMetrics).logDataToUpperLayer(eq(mockUwbSession), eq(1)); 407 } 408 409 // Test scenario for receiving Application payload data followed by a RANGE_DATA_NTF with an 410 // OWR Aoa Measurement (such that the ShortMacAddress format is used for the remote device). 411 @Test onRangeDataNotificationReceived_owrAoa_success_shortMacAddress()412 public void onRangeDataNotificationReceived_owrAoa_success_shortMacAddress() 413 throws RemoteException { 414 UwbSession mockUwbSession = mock(UwbSession.class); 415 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 416 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 417 doReturn(mockUwbSession) 418 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 419 UwbOemExtensionCallbackListener mUwbOemExtensionCallbackListener = 420 mock(UwbOemExtensionCallbackListener.class); 421 when(mUwbServiceCore.isOemExtensionCbRegistered()).thenReturn(true); 422 when(mUwbServiceCore.getOemExtensionCallback()) 423 .thenReturn(mUwbOemExtensionCallbackListener); 424 when(mUwbOemExtensionCallbackListener.onCheckPointedTarget(any())).thenReturn(true); 425 426 // First call onDataReceived() to get the application payload data. This should always have 427 // the MacAddress (in 8 Bytes), even for a Short MacAddress (MSB are zeroed out). 428 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 429 DATA_SEQUENCE_NUM, PEER_EXTENDED_SHORT_MAC_ADDRESS, 430 SOURCE_END_POINT, DEST_END_POINT, DATA_PAYLOAD); 431 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 432 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 433 434 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 435 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 436 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_SHORT, 437 UwbUciConstants.STATUS_CODE_OK); 438 Params firaParams = setupFiraParams( 439 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 440 when(mockUwbSession.getParams()).thenReturn(firaParams); 441 when(mUwbAdvertiseManager.isPointedTarget(PEER_SHORT_MAC_ADDRESS)).thenReturn(true); 442 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_SHORT_MAC_ADDRESS_LONG)) 443 .thenReturn(List.of(buildReceivedDataInfo(PEER_EXTENDED_SHORT_MAC_ADDRESS_LONG))); 444 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 445 446 verify(mUwbSessionNotificationManager) 447 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 448 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 449 verify(mUwbSessionNotificationManager) 450 .onDataReceived(eq(mockUwbSession), eq(PEER_SHORT_UWB_ADDRESS), 451 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 452 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_SHORT_MAC_ADDRESS_LONG); 453 verify(mUwbMetrics).logDataToUpperLayer(eq(mockUwbSession), eq(1)); 454 } 455 456 // Test scenario for receiving Application payload data followed by a RANGE_DATA_NTF with an 457 // OWR Aoa Measurement, from Multiple advertiser devices in a UWB session. 458 @Test onRangeDataNotificationReceived_owrAoa_success_multipleAdvertisers()459 public void onRangeDataNotificationReceived_owrAoa_success_multipleAdvertisers() { 460 UwbSession mockUwbSession = mock(UwbSession.class); 461 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 462 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 463 doReturn(mockUwbSession) 464 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 465 466 // First call onDataReceived() to get the application payload data. 467 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 468 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 469 DATA_PAYLOAD); 470 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 471 DATA_SEQUENCE_NUM_1, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 472 DATA_PAYLOAD); 473 474 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 475 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS_2, SOURCE_END_POINT, DEST_END_POINT, 476 DATA_PAYLOAD); 477 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 478 DATA_SEQUENCE_NUM_1, PEER_EXTENDED_MAC_ADDRESS_2, SOURCE_END_POINT, DEST_END_POINT, 479 DATA_PAYLOAD); 480 481 verify(mockUwbSession, times(4)).addReceivedDataInfo( 482 isA(UwbSessionManager.ReceivedDataInfo.class)); 483 verify(mUwbMetrics, times(4)).logDataRx( 484 eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 485 486 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 487 UwbRangingData uwbRangingData1 = UwbTestUtils.generateRangingData( 488 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 489 PEER_EXTENDED_MAC_ADDRESS, UwbUciConstants.STATUS_CODE_OK); 490 UwbRangingData uwbRangingData2 = UwbTestUtils.generateRangingData( 491 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 492 PEER_EXTENDED_MAC_ADDRESS_2, UwbUciConstants.STATUS_CODE_OK); 493 Params firaParams = setupFiraParams( 494 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 495 when(mockUwbSession.getParams()).thenReturn(firaParams); 496 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(true); 497 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS_2)).thenReturn(true); 498 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)) 499 .thenReturn(List.of( 500 buildReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM), 501 buildReceivedDataInfo( 502 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM_1))); 503 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_2_LONG)) 504 .thenReturn(List.of( 505 buildReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_2_LONG, DATA_SEQUENCE_NUM), 506 buildReceivedDataInfo( 507 PEER_EXTENDED_MAC_ADDRESS_2_LONG, DATA_SEQUENCE_NUM_1))); 508 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData1); 509 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData2); 510 511 verify(mUwbSessionNotificationManager) 512 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData1)); 513 verify(mUwbSessionNotificationManager) 514 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData2)); 515 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData1.mRangingOwrAoaMeasure); 516 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData2.mRangingOwrAoaMeasure); 517 verify(mUwbSessionNotificationManager, times(2)) 518 .onDataReceived(eq(mockUwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 519 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 520 verify(mUwbSessionNotificationManager, times(2)) 521 .onDataReceived(eq(mockUwbSession), eq(PEER_EXTENDED_UWB_ADDRESS_2), 522 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 523 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_EXTENDED_MAC_ADDRESS_LONG); 524 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_EXTENDED_MAC_ADDRESS_2_LONG); 525 verify(mUwbMetrics, times(2)).logDataToUpperLayer(eq(mockUwbSession), eq(2)); 526 } 527 528 @Test onRangeDataNotificationReceived_owrAoa_CheckPointedTarget_Failed()529 public void onRangeDataNotificationReceived_owrAoa_CheckPointedTarget_Failed() 530 throws RemoteException { 531 UwbSession mockUwbSession = mock(UwbSession.class); 532 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 533 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 534 doReturn(mockUwbSession) 535 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 536 UwbOemExtensionCallbackListener mUwbOemExtensionCallbackListener = 537 mock(UwbOemExtensionCallbackListener.class); 538 when(mUwbServiceCore.isOemExtensionCbRegistered()).thenReturn(true); 539 when(mUwbServiceCore.getOemExtensionCallback()) 540 .thenReturn(mUwbOemExtensionCallbackListener); 541 when(mUwbOemExtensionCallbackListener.onCheckPointedTarget(any())).thenReturn(false); 542 543 // First call onDataReceived() to get the application payload data. This should always have 544 // the MacAddress (in 8 Bytes), even for a Short MacAddress (MSB are zeroed out). 545 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 546 DATA_SEQUENCE_NUM, PEER_EXTENDED_SHORT_MAC_ADDRESS, 547 SOURCE_END_POINT, DEST_END_POINT, DATA_PAYLOAD); 548 549 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 550 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 551 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_SHORT, 552 UwbUciConstants.STATUS_CODE_OK); 553 Params firaParams = setupFiraParams( 554 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 555 when(mockUwbSession.getParams()).thenReturn(firaParams); 556 when(mUwbAdvertiseManager.isPointedTarget(PEER_SHORT_MAC_ADDRESS)).thenReturn(true); 557 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 558 559 verify(mUwbSessionNotificationManager) 560 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 561 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 562 verify(mUwbSessionNotificationManager, never()) 563 .onDataReceived(eq(mockUwbSession), eq(PEER_SHORT_UWB_ADDRESS), 564 isA(PersistableBundle.class), eq(DATA_PAYLOAD)); 565 verify(mUwbAdvertiseManager, never()).removeAdvertiseTarget(PEER_SHORT_MAC_ADDRESS_LONG); 566 } 567 568 @Test onRangeDataNotificationReceived_owrAoa_missingUwbSession()569 public void onRangeDataNotificationReceived_owrAoa_missingUwbSession() { 570 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 571 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 572 UwbUciConstants.STATUS_CODE_OK); 573 574 // Setup the test scenario such that the UwbSession (from the RANGE_DATA_NTF) doesn't exist. 575 doReturn(null) 576 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 577 578 // First call onDataReceived() to get the application payload data. 579 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 580 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 581 DATA_PAYLOAD); 582 583 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 584 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 585 586 verifyZeroInteractions(mUwbAdvertiseManager, mUwbSessionNotificationManager, mUwbMetrics); 587 } 588 589 @Test onRangeDataNotificationReceived_incorrectRangingMeasureType()590 public void onRangeDataNotificationReceived_incorrectRangingMeasureType() { 591 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 592 RANGING_MEASUREMENT_TYPE_UNDEFINED, MAC_ADDRESSING_MODE_EXTENDED, 593 UwbUciConstants.STATUS_CODE_OK); 594 UwbSession mockUwbSession = mock(UwbSession.class); 595 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 596 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 597 doReturn(mockUwbSession) 598 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 599 600 // First call onDataReceived() to get the application payload data. 601 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 602 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 603 DATA_PAYLOAD); 604 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 605 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 606 607 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 608 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 609 610 verify(mUwbSessionNotificationManager) 611 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 612 verifyZeroInteractions(mUwbAdvertiseManager); 613 } 614 615 @Test onRangeDataNotificationReceived_owrAoa_incorrectRangingRoundUsage()616 public void onRangeDataNotificationReceived_owrAoa_incorrectRangingRoundUsage() { 617 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 618 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 619 UwbUciConstants.STATUS_CODE_OK); 620 UwbSession mockUwbSession = mock(UwbSession.class); 621 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 622 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 623 doReturn(mockUwbSession) 624 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 625 626 // First call onDataReceived() to get the application payload data. 627 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 628 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 629 DATA_PAYLOAD); 630 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 631 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 632 633 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF (with an 634 // incorrect RangingRoundUsage value). 635 Params firaParams = setupFiraParams( 636 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_DS_TWR_DEFERRED_MODE)); 637 when(mockUwbSession.getParams()).thenReturn(firaParams); 638 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 639 640 verify(mUwbSessionNotificationManager) 641 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 642 verifyZeroInteractions(mUwbAdvertiseManager); 643 } 644 645 @Test onRangeDataNotificationReceived_owrAoa_incorrectDeviceRole()646 public void onRangeDataNotificationReceived_owrAoa_incorrectDeviceRole() { 647 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 648 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 649 UwbUciConstants.STATUS_CODE_OK); 650 UwbSession mockUwbSession = mock(UwbSession.class); 651 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 652 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 653 doReturn(mockUwbSession) 654 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 655 656 // First call onDataReceived() to get the application payload data. 657 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 658 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 659 DATA_PAYLOAD); 660 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 661 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 662 663 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 664 Params firaParams = setupFiraParams( 665 RANGING_DEVICE_ROLE_ADVERTISER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 666 when(mockUwbSession.getParams()).thenReturn(firaParams); 667 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 668 669 verify(mUwbSessionNotificationManager) 670 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 671 verifyZeroInteractions(mUwbAdvertiseManager); 672 } 673 674 @Test onRangeDataNotificationReceived_owrAoa_receivedDataNotCalled()675 public void onRangeDataNotificationReceived_owrAoa_receivedDataNotCalled() { 676 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 677 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 678 UwbUciConstants.STATUS_CODE_OK); 679 UwbSession mockUwbSession = mock(UwbSession.class); 680 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 681 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 682 doReturn(mockUwbSession) 683 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 684 685 // Skip call to mUwbSessionManager.onDataReceived(). This means there is no application 686 // payload data, and so mUwbSessionNotificationManager.onDataReceived() shouldn't be called. 687 Params firaParams = setupFiraParams( 688 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 689 when(mockUwbSession.getParams()).thenReturn(firaParams); 690 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(true); 691 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)) 692 .thenReturn(List.of()); 693 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 694 695 verify(mUwbSessionNotificationManager) 696 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 697 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 698 verifyZeroInteractions(mUwbSessionNotificationManager); 699 verify(mUwbMetrics, never()).logDataToUpperLayer(eq(mockUwbSession), anyInt()); 700 } 701 702 @Test onRangeDataNotificationReceived_owrAoa_receivedDataDifferentMacAddress()703 public void onRangeDataNotificationReceived_owrAoa_receivedDataDifferentMacAddress() { 704 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 705 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 706 UwbUciConstants.STATUS_CODE_OK); 707 UwbSession mockUwbSession = mock(UwbSession.class); 708 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 709 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 710 doReturn(mockUwbSession) 711 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 712 713 // onDataReceived() called for a different MacAddress, which should be equivalent to it 714 // not being called. 715 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 716 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS_2, SOURCE_END_POINT, DEST_END_POINT, 717 DATA_PAYLOAD); 718 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 719 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 720 721 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. 722 Params firaParams = setupFiraParams( 723 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 724 when(mockUwbSession.getParams()).thenReturn(firaParams); 725 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(true); 726 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)) 727 .thenReturn(List.of()); 728 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 729 730 verify(mUwbSessionNotificationManager) 731 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 732 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 733 verifyZeroInteractions(mUwbSessionNotificationManager); 734 verify(mUwbMetrics, never()).logDataToUpperLayer(eq(mockUwbSession), anyInt()); 735 } 736 737 @Test onRangeDataNotificationReceived_owrAoa_receivedDataDifferentUwbSession()738 public void onRangeDataNotificationReceived_owrAoa_receivedDataDifferentUwbSession() { 739 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 740 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 741 UwbUciConstants.STATUS_CODE_OK); 742 UwbSession mockUwbSession = mock(UwbSession.class); 743 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 744 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 745 doReturn(mockUwbSession) 746 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 747 UwbSession mockUwbSession2 = mock(UwbSession.class); 748 when(mockUwbSession2.getWaitObj()).thenReturn(mock(WaitObj.class)); 749 when(mockUwbSession2.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 750 doReturn(mockUwbSession2) 751 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID_2)); 752 753 // onDataReceived() called for a different UwbSessionID, which should be equivalent to it 754 // not being called. 755 mUwbSessionManager.onDataReceived(TEST_SESSION_ID_2, UwbUciConstants.STATUS_CODE_OK, 756 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 757 DATA_PAYLOAD); 758 verify(mockUwbSession2).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 759 verify(mUwbMetrics).logDataRx(eq(mockUwbSession2), eq(UwbUciConstants.STATUS_CODE_OK)); 760 761 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. Setup such 762 // that there is no ReceivedDataInfo returned for the UwbSession (to simulate the test 763 // scenario). 764 Params firaParams = setupFiraParams( 765 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 766 when(mockUwbSession.getParams()).thenReturn(firaParams); 767 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(true); 768 when(mockUwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)) 769 .thenReturn(List.of()); 770 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 771 772 verify(mUwbSessionNotificationManager) 773 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 774 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 775 verifyZeroInteractions(mUwbSessionNotificationManager); 776 verify(mUwbMetrics, never()).logDataToUpperLayer(eq(mockUwbSession), anyInt()); 777 } 778 779 @Test onRangeDataNotificationReceived_owrAoa_notPointedTarget()780 public void onRangeDataNotificationReceived_owrAoa_notPointedTarget() { 781 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 782 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 783 UwbUciConstants.STATUS_CODE_OK); 784 UwbSession mockUwbSession = mock(UwbSession.class); 785 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 786 when(mockUwbSession.getRangingRoundUsage()).thenReturn(ROUND_USAGE_OWR_AOA_MEASUREMENT); 787 doReturn(mockUwbSession) 788 .when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 789 790 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 791 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 792 DATA_PAYLOAD); 793 verify(mockUwbSession).addReceivedDataInfo(isA(UwbSessionManager.ReceivedDataInfo.class)); 794 verify(mUwbMetrics).logDataRx(eq(mockUwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 795 796 // Setup isPointedTarget() to return false. 797 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(false); 798 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 799 800 verify(mUwbSessionNotificationManager) 801 .onRangingResult(eq(mockUwbSession), eq(uwbRangingData)); 802 verify(mUwbAdvertiseManager, never()).removeAdvertiseTarget(isA(Long.class)); 803 verifyZeroInteractions(mUwbSessionNotificationManager); 804 } 805 806 @Test onMulticastListUpdateNotificationReceivedWithValidSession()807 public void onMulticastListUpdateNotificationReceivedWithValidSession() { 808 UwbMulticastListUpdateStatus mockUwbMulticastListUpdateStatus = 809 mock(UwbMulticastListUpdateStatus.class); 810 UwbSession mockUwbSession = mock(UwbSession.class); 811 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 812 doReturn(mockUwbSession) 813 .when(mUwbSessionManager).getUwbSession(anyInt()); 814 815 mUwbSessionManager.onMulticastListUpdateNotificationReceived( 816 mockUwbMulticastListUpdateStatus); 817 818 verify(mockUwbSession, times(2)).getWaitObj(); 819 verify(mockUwbSession) 820 .setMulticastListUpdateStatus(eq(mockUwbMulticastListUpdateStatus)); 821 } 822 823 @Test onSessionStatusNotificationReceived_max_retry()824 public void onSessionStatusNotificationReceived_max_retry() { 825 UwbSession mockUwbSession = mock(UwbSession.class); 826 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 827 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 828 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 829 when(mockUwbSession.getSessionState()).thenReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE); 830 831 mUwbSessionManager.onSessionStatusNotificationReceived( 832 TEST_SESSION_ID, 833 UwbUciConstants.UWB_SESSION_STATE_IDLE, 834 UwbUciConstants.REASON_MAX_RANGING_ROUND_RETRY_COUNT_REACHED); 835 836 verify(mockUwbSession, times(2)).getWaitObj(); 837 verify(mockUwbSession).setSessionState(eq(UwbUciConstants.UWB_SESSION_STATE_IDLE)); 838 verify(mUwbSessionNotificationManager).onRangingStoppedWithUciReasonCode( 839 eq(mockUwbSession), 840 eq(UwbUciConstants.REASON_MAX_RANGING_ROUND_RETRY_COUNT_REACHED)); 841 } 842 843 @Test onSessionStatusNotificationReceived_session_mgmt_cmds()844 public void onSessionStatusNotificationReceived_session_mgmt_cmds() { 845 UwbSession mockUwbSession = mock(UwbSession.class); 846 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 847 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 848 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 849 when(mockUwbSession.getSessionState()).thenReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE); 850 851 mUwbSessionManager.onSessionStatusNotificationReceived( 852 TEST_SESSION_ID, 853 UwbUciConstants.UWB_SESSION_STATE_IDLE, 854 UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS); 855 856 verify(mockUwbSession, times(2)).getWaitObj(); 857 verify(mockUwbSession).setSessionState(eq(UwbUciConstants.UWB_SESSION_STATE_IDLE)); 858 verify(mUwbSessionNotificationManager, never()).onRangingStoppedWithUciReasonCode( 859 any(), anyInt()); 860 } 861 862 @Test initSession_ExistedSession()863 public void initSession_ExistedSession() throws RemoteException { 864 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 865 doReturn(true).when(mUwbSessionManager).isExistedSession(anyInt()); 866 867 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mock(SessionHandle.class), 868 TEST_SESSION_ID, TEST_SESSION_TYPE, "any", mock(Params.class), mockRangingCallbacks, 869 TEST_CHIP_ID); 870 871 verify(mockRangingCallbacks).onRangingOpenFailed( 872 any(), eq(RangingChangeReason.BAD_PARAMETERS), any()); 873 assertThat(mTestLooper.nextMessage()).isNull(); 874 } 875 876 @Test initFiraSession_maxSessionsExceeded()877 public void initFiraSession_maxSessionsExceeded() throws RemoteException { 878 doReturn(MAX_FIRA_SESSION_NUM).when(mUwbSessionManager).getFiraSessionCount(); 879 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 880 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 881 882 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mock(SessionHandle.class), 883 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mock(Params.class), 884 mockRangingCallbacks, 885 TEST_CHIP_ID); 886 887 verify(mockRangingCallbacks).onRangingOpenFailed(any(), 888 eq(RangingChangeReason.MAX_SESSIONS_REACHED), any()); 889 assertThat(mTestLooper.nextMessage()).isNull(); 890 } 891 892 @Test initCccSession_maxSessionsExceeded()893 public void initCccSession_maxSessionsExceeded() throws RemoteException { 894 doReturn(MAX_CCC_SESSION_NUM).when(mUwbSessionManager).getCccSessionCount(); 895 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 896 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 897 898 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mock(SessionHandle.class), 899 TEST_SESSION_ID, TEST_SESSION_TYPE, CccParams.PROTOCOL_NAME, mock(Params.class), 900 mockRangingCallbacks, 901 TEST_CHIP_ID); 902 903 verify(mockRangingCallbacks).onRangingOpenFailed(any(), 904 eq(RangingChangeReason.MAX_SESSIONS_REACHED), any()); 905 assertThat(mTestLooper.nextMessage()).isNull(); 906 } 907 908 @Test initSession_UwbSession_RemoteException()909 public void initSession_UwbSession_RemoteException() throws RemoteException { 910 doReturn(0).when(mUwbSessionManager).getSessionCount(); 911 doReturn(0L).when(mUwbSessionManager).getCccSessionCount(); 912 doReturn(0L).when(mUwbSessionManager).getFiraSessionCount(); 913 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 914 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 915 SessionHandle mockSessionHandle = mock(SessionHandle.class); 916 Params mockParams = mock(FiraParams.class); 917 IBinder mockBinder = mock(IBinder.class); 918 UwbSession uwbSession = spy( 919 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE, mockSessionHandle, 920 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, 921 mockRangingCallbacks, TEST_CHIP_ID)); 922 doReturn(mockBinder).when(uwbSession).getBinder(); 923 doReturn(uwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), anyInt(), 924 anyByte(), anyString(), any(), any(), anyString()); 925 doThrow(new RemoteException()).when(mockBinder).linkToDeath(any(), anyInt()); 926 927 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mockSessionHandle, TEST_SESSION_ID, 928 TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, mockRangingCallbacks, 929 TEST_CHIP_ID); 930 931 verify(uwbSession).binderDied(); 932 verify(mockRangingCallbacks).onRangingOpenFailed(any(), anyInt(), any()); 933 verify(mockBinder, atLeast(1)).unlinkToDeath(any(), anyInt()); 934 assertThat(mTestLooper.nextMessage()).isNull(); 935 } 936 937 @Test initSession_success()938 public void initSession_success() throws RemoteException { 939 doReturn(0).when(mUwbSessionManager).getSessionCount(); 940 doReturn(0L).when(mUwbSessionManager).getCccSessionCount(); 941 doReturn(0L).when(mUwbSessionManager).getFiraSessionCount(); 942 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 943 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 944 SessionHandle mockSessionHandle = mock(SessionHandle.class); 945 Params mockParams = mock(FiraParams.class); 946 IBinder mockBinder = mock(IBinder.class); 947 948 UwbSession uwbSession = spy( 949 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE, mockSessionHandle, 950 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, 951 mockRangingCallbacks, TEST_CHIP_ID)); 952 doReturn(mockBinder).when(uwbSession).getBinder(); 953 doReturn(uwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), anyInt(), 954 anyByte(), anyString(), any(), any(), anyString()); 955 956 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mockSessionHandle, TEST_SESSION_ID, 957 TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, mockRangingCallbacks, 958 TEST_CHIP_ID); 959 960 verify(uwbSession, never()).binderDied(); 961 verify(mockRangingCallbacks, never()).onRangingOpenFailed(any(), anyInt(), any()); 962 verify(mockBinder, never()).unlinkToDeath(any(), anyInt()); 963 assertThat(mUwbSessionManager.getUwbSession(TEST_SESSION_ID)).isEqualTo(uwbSession); 964 assertThat(mTestLooper.nextMessage().what).isEqualTo(1); // SESSION_OPEN_RANGING 965 } 966 967 @Test initSessionMaxSessions_lowestPrioritySessionReplaced()968 public void initSessionMaxSessions_lowestPrioritySessionReplaced() throws RemoteException { 969 doReturn(false).when(mUwbInjector).isSystemApp(UID, PACKAGE_NAME); 970 doReturn(true).when(mUwbInjector).isSystemApp(UID_2, PACKAGE_NAME_2); 971 doReturn(1L).when(mUwbSessionManager).getMaxFiraSessionsNumber(TEST_CHIP_ID); 972 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 973 Params mockParams = mock(FiraParams.class); 974 IBinder mockBinder = mock(IBinder.class); 975 976 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 977 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 978 when(mNativeUwbManager.deInitSession(anyInt(), anyString())) 979 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 980 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 981 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 982 983 // Init session for 3rd party FG app 984 UwbSession lowPrioUwbSession = spy( 985 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE, SESSION_HANDLE, 986 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, 987 mockRangingCallbacks, TEST_CHIP_ID)); 988 doReturn(lowPrioUwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), 989 anyInt(), 990 anyByte(), anyString(), any(), any(), anyString()); 991 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 992 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(lowPrioUwbSession).getSessionState(); 993 doReturn(mock(WaitObj.class)).when(lowPrioUwbSession).getWaitObj(); 994 doReturn(mockBinder).when(lowPrioUwbSession).getBinder(); 995 996 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, SESSION_HANDLE, TEST_SESSION_ID, 997 TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, mockRangingCallbacks, 998 TEST_CHIP_ID); 999 1000 assertThat(mUwbSessionManager.getUwbSession(TEST_SESSION_ID)).isEqualTo(lowPrioUwbSession); 1001 mTestLooper.dispatchNext(); 1002 1003 // Init session for system app 1004 UwbSession highPrioUwbSession = spy( 1005 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE_2, SESSION_HANDLE_2, 1006 TEST_SESSION_ID_2, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, 1007 mockRangingCallbacks, TEST_CHIP_ID)); 1008 doReturn(mockBinder).when(highPrioUwbSession).getBinder(); 1009 doReturn(mock(WaitObj.class)).when(highPrioUwbSession).getWaitObj(); 1010 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1011 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(highPrioUwbSession).getSessionState(); 1012 doReturn(highPrioUwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), 1013 anyInt(), 1014 anyByte(), anyString(), any(), any(), anyString()); 1015 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE_2, SESSION_HANDLE_2, TEST_SESSION_ID_2, 1016 TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, mockRangingCallbacks, 1017 TEST_CHIP_ID); 1018 mTestLooper.dispatchAll(); 1019 1020 verify(mNativeUwbManager).initSession(TEST_SESSION_ID, TEST_SESSION_TYPE, TEST_CHIP_ID); 1021 verify(mNativeUwbManager).deInitSession(TEST_SESSION_ID, TEST_CHIP_ID); 1022 verify(mNativeUwbManager).initSession(TEST_SESSION_ID_2, TEST_SESSION_TYPE, TEST_CHIP_ID); 1023 verify(mockRangingCallbacks, never()).onRangingOpenFailed(any(), anyInt(), any()); 1024 verify(mUwbSessionNotificationManager).onRangingOpened(lowPrioUwbSession); 1025 verify(mUwbSessionNotificationManager).onRangingClosed(lowPrioUwbSession, 1026 UwbUciConstants.STATUS_CODE_ERROR_MAX_SESSIONS_EXCEEDED); 1027 verify(mUwbSessionNotificationManager).onRangingOpened(highPrioUwbSession); 1028 assertThat(mUwbSessionManager.getUwbSession(TEST_SESSION_ID)).isNull(); 1029 assertThat(mUwbSessionManager.getUwbSession(TEST_SESSION_ID_2)).isEqualTo( 1030 highPrioUwbSession); 1031 } 1032 1033 @Test testNeedsAppConfigUpdate_setAppConfigCalledOnStartRanging()1034 public void testNeedsAppConfigUpdate_setAppConfigCalledOnStartRanging() throws RemoteException { 1035 UwbSession mockUwbSession = mock(UwbSession.class); 1036 1037 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1038 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1039 doReturn(mockUwbSession).when(mUwbSessionManager).getUwbSession(anyInt()); 1040 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE) 1041 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1042 doReturn(PROTOCOL_NAME).when(mockUwbSession).getProtocolName(); 1043 doReturn(mock(WaitObj.class)).when(mockUwbSession).getWaitObj(); 1044 when(mockUwbSession.getNeedsAppConfigUpdate()).thenReturn(true); 1045 1046 mUwbSessionManager.startRanging(mock(SessionHandle.class), mock(Params.class)); 1047 mTestLooper.dispatchAll(); 1048 1049 verify(mUwbConfigurationManager).setAppConfigurations(anyInt(), any(), 1050 any()); 1051 } 1052 1053 @Test testCreateUwbSession_correctSessionPrioritiesSet()1054 public void testCreateUwbSession_correctSessionPrioritiesSet() throws RemoteException { 1055 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 1056 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1057 FiraOpenSessionParams mockFiraOpenSessionParams = mock(FiraOpenSessionParams.class); 1058 Params mockCccParams = mock(CccParams.class); 1059 FiraOpenSessionParams.Builder mockFiraBuilder = mock(FiraOpenSessionParams.Builder.class); 1060 1061 when(mockFiraOpenSessionParams.toBuilder()).thenReturn(mockFiraBuilder); 1062 when(mockFiraBuilder.setSessionPriority(anyInt())).thenReturn(mockFiraBuilder); 1063 when(mockFiraBuilder.build()).thenReturn(mockFiraOpenSessionParams); 1064 when(mockFiraOpenSessionParams.getSessionPriority()).thenReturn( 1065 UwbSession.DEFAULT_SESSION_PRIORITY); 1066 1067 // System session 1068 String systemPackageName = "com.google.uwb"; 1069 when(mUwbInjector.isSystemApp(UID, systemPackageName)).thenReturn(true); 1070 AttributionSource attributionSourceSystemApp = 1071 new AttributionSource.Builder(UID).setPackageName(systemPackageName).build(); 1072 UwbSession systemUwbSession = 1073 mUwbSessionManager.new UwbSession(attributionSourceSystemApp, mockSessionHandle, 1074 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1075 mockFiraOpenSessionParams, 1076 mockRangingCallbacks, TEST_CHIP_ID); 1077 1078 assertThat(systemUwbSession.getStackSessionPriority()).isEqualTo( 1079 UwbSession.SYSTEM_APP_SESSION_PRIORITY); 1080 verify(mockFiraBuilder).setSessionPriority(UwbSession.SYSTEM_APP_SESSION_PRIORITY); 1081 1082 // CCC session 1083 UwbSession cccUwbSession = 1084 mUwbSessionManager.new UwbSession(attributionSourceSystemApp, mockSessionHandle, 1085 TEST_SESSION_ID, TEST_SESSION_TYPE, CccParams.PROTOCOL_NAME, mockCccParams, 1086 mockRangingCallbacks, TEST_CHIP_ID); 1087 1088 assertThat(cccUwbSession.getStackSessionPriority()).isEqualTo( 1089 UwbSession.CCC_SESSION_PRIORITY); 1090 1091 // 3rd party foreground session 1092 String nonSystemPackageName = "com.something.app"; 1093 when(mUwbInjector.isForegroundAppOrService(UID, nonSystemPackageName)) 1094 .thenReturn(true); 1095 AttributionSource attributionSourceNonSystemApp = 1096 new AttributionSource.Builder(UID).setPackageName(nonSystemPackageName).build(); 1097 UwbSession nonSystemFgUwbSession = 1098 mUwbSessionManager.new UwbSession(attributionSourceNonSystemApp, mockSessionHandle, 1099 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1100 mockFiraOpenSessionParams, 1101 mockRangingCallbacks, TEST_CHIP_ID); 1102 1103 assertThat(nonSystemFgUwbSession.getStackSessionPriority()).isEqualTo( 1104 UwbSession.FG_SESSION_PRIORITY); 1105 verify(mockFiraBuilder).setSessionPriority(UwbSession.FG_SESSION_PRIORITY); 1106 1107 1108 // 3rd party background session 1109 when(mUwbInjector.isForegroundAppOrService(UID, nonSystemPackageName)) 1110 .thenReturn(false); 1111 UwbSession nonSystemBgUwbSession = 1112 mUwbSessionManager.new UwbSession(attributionSourceNonSystemApp, mockSessionHandle, 1113 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1114 mockFiraOpenSessionParams, 1115 mockRangingCallbacks, TEST_CHIP_ID); 1116 1117 assertThat(nonSystemBgUwbSession.getStackSessionPriority()).isEqualTo( 1118 UwbSession.BG_SESSION_PRIORITY); 1119 verify(mockFiraBuilder).setSessionPriority(UwbSession.BG_SESSION_PRIORITY); 1120 1121 } 1122 1123 @Test initSession_controleeList()1124 public void initSession_controleeList() throws RemoteException { 1125 doReturn(0).when(mUwbSessionManager).getSessionCount(); 1126 doReturn(0L).when(mUwbSessionManager).getCccSessionCount(); 1127 doReturn(0L).when(mUwbSessionManager).getFiraSessionCount(); 1128 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 1129 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 1130 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1131 FiraOpenSessionParams mockParams = mock(FiraOpenSessionParams.class); 1132 FiraOpenSessionParams.Builder mockBuilder = mock(FiraOpenSessionParams.Builder.class); 1133 IBinder mockBinder = mock(IBinder.class); 1134 1135 when(mockParams.getDestAddressList()) 1136 .thenReturn(Collections.singletonList(UWB_DEST_ADDRESS)); 1137 when(mockParams.toBuilder()).thenReturn(mockBuilder); 1138 when(mockBuilder.setSessionPriority(anyInt())).thenReturn(mockBuilder); 1139 when(mockBuilder.build()).thenReturn(mockParams); 1140 1141 UwbSession uwbSession = spy( 1142 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE, mockSessionHandle, 1143 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, 1144 mockRangingCallbacks, TEST_CHIP_ID)); 1145 doReturn(mockBinder).when(uwbSession).getBinder(); 1146 doReturn(uwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), anyInt(), 1147 anyByte(), anyString(), any(), any(), anyString()); 1148 1149 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, mockSessionHandle, TEST_SESSION_ID, 1150 TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, mockParams, mockRangingCallbacks, 1151 TEST_CHIP_ID); 1152 1153 assertThat(uwbSession.getControleeList().size() == 1 1154 && uwbSession.getControleeList().get(0).getUwbAddress().equals(UWB_DEST_ADDRESS)) 1155 .isTrue(); 1156 1157 assertThat(uwbSession.getControlee(UWB_DEST_ADDRESS) 1158 .getUwbAddress().equals(UWB_DEST_ADDRESS)).isTrue(); 1159 1160 verify(uwbSession, never()).binderDied(); 1161 verify(mockRangingCallbacks, never()).onRangingOpenFailed(any(), anyInt(), any()); 1162 verify(mockBinder, never()).unlinkToDeath(any(), anyInt()); 1163 assertThat(mUwbSessionManager.getUwbSession(TEST_SESSION_ID)).isEqualTo(uwbSession); 1164 assertThat(mTestLooper.nextMessage().what).isEqualTo(1); // SESSION_OPEN_RANGING 1165 } 1166 1167 @Test startRanging_notExistedSession()1168 public void startRanging_notExistedSession() { 1169 doReturn(false).when(mUwbSessionManager).isExistedSession(any()); 1170 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1171 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1172 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE) 1173 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1174 1175 mUwbSessionManager.startRanging(mock(SessionHandle.class), mock(Params.class)); 1176 1177 assertThat(mTestLooper.nextMessage()).isNull(); 1178 } 1179 1180 @Test startRanging_currentSessionStateIdle()1181 public void startRanging_currentSessionStateIdle() { 1182 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1183 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1184 UwbSession uwbSession = mock(UwbSession.class); 1185 when(uwbSession.getProtocolName()).thenReturn(FiraParams.PROTOCOL_NAME); 1186 doReturn(uwbSession).when(mUwbSessionManager).getUwbSession(anyInt()); 1187 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE) 1188 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1189 1190 mUwbSessionManager.startRanging(mock(SessionHandle.class), mock(Params.class)); 1191 1192 assertThat(mTestLooper.nextMessage().what).isEqualTo(2); // SESSION_START_RANGING 1193 } 1194 1195 @Test startRanging_currentSessionStateActive()1196 public void startRanging_currentSessionStateActive() { 1197 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1198 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1199 UwbSession mockUwbSession = mock(UwbSession.class); 1200 doReturn(mockUwbSession).when(mUwbSessionManager).getUwbSession(anyInt()); 1201 when(mockUwbSession.getProtocolName()).thenReturn(CccParams.PROTOCOL_NAME); 1202 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 1203 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1204 1205 mUwbSessionManager.startRanging(mock(SessionHandle.class), mock(Params.class)); 1206 1207 verify(mUwbSessionNotificationManager).onRangingStartFailed( 1208 any(), eq(UwbUciConstants.STATUS_CODE_REJECTED)); 1209 } 1210 1211 @Test startRanging_currentSessiionStateInvalid()1212 public void startRanging_currentSessiionStateInvalid() { 1213 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1214 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1215 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1216 doReturn(UwbUciConstants.UWB_SESSION_STATE_ERROR) 1217 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1218 1219 mUwbSessionManager.startRanging(mock(SessionHandle.class), mock(Params.class)); 1220 1221 verify(mUwbSessionNotificationManager) 1222 .onRangingStartFailed(any(), eq(UwbUciConstants.STATUS_CODE_FAILED)); 1223 } 1224 1225 @Test stopRanging_notExistedSession()1226 public void stopRanging_notExistedSession() { 1227 doReturn(false).when(mUwbSessionManager).isExistedSession(any()); 1228 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1229 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1230 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 1231 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1232 1233 mUwbSessionManager.stopRanging(mock(SessionHandle.class)); 1234 1235 assertThat(mTestLooper.nextMessage()).isNull(); 1236 } 1237 1238 @Test stopRanging_currentSessionStateActive()1239 public void stopRanging_currentSessionStateActive() { 1240 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1241 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1242 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1243 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 1244 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1245 1246 mUwbSessionManager.stopRanging(mock(SessionHandle.class)); 1247 1248 assertThat(mTestLooper.nextMessage().what).isEqualTo(3); // SESSION_STOP_RANGING 1249 } 1250 1251 @Test stopRanging_currentSessionStateActive_owrAoa()1252 public void stopRanging_currentSessionStateActive_owrAoa() { 1253 UwbSession mockUwbSession = mock(UwbSession.class); 1254 1255 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1256 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1257 doReturn(mockUwbSession).when(mUwbSessionManager).getUwbSession(anyInt()); 1258 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 1259 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1260 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 1261 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1262 1263 doReturn(PROTOCOL_NAME).when(mockUwbSession).getProtocolName(); 1264 doReturn(0).when(mockUwbSession).getCurrentFiraRangingIntervalMs(); 1265 1266 // Setup the UwbSession to have the peer device's MacAddress stored (which happens when 1267 // a valid RANGE_DATA_NTF with an OWR AoA Measurement is received). 1268 doReturn(Set.of(PEER_EXTENDED_MAC_ADDRESS_LONG)).when(mockUwbSession) 1269 .getRemoteMacAddressList(); 1270 1271 mUwbSessionManager.stopRanging(mock(SessionHandle.class)); 1272 mTestLooper.dispatchNext(); 1273 1274 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_EXTENDED_MAC_ADDRESS_LONG); 1275 } 1276 1277 @Test stopRanging_currentSessionStateIdle()1278 public void stopRanging_currentSessionStateIdle() { 1279 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1280 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1281 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1282 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE) 1283 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1284 1285 mUwbSessionManager.stopRanging(mock(SessionHandle.class)); 1286 1287 verify(mUwbSessionNotificationManager).onRangingStopped(any(), 1288 eq(UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS)); 1289 } 1290 1291 @Test stopRanging_currentSessionStateInvalid()1292 public void stopRanging_currentSessionStateInvalid() { 1293 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 1294 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1295 doReturn(mock(UwbSession.class)).when(mUwbSessionManager).getUwbSession(anyInt()); 1296 doReturn(UwbUciConstants.UWB_SESSION_STATE_ERROR) 1297 .when(mUwbSessionManager).getCurrentSessionState(anyInt()); 1298 1299 mUwbSessionManager.stopRanging(mock(SessionHandle.class)); 1300 1301 verify(mUwbSessionNotificationManager).onRangingStopFailed(any(), 1302 eq(UwbUciConstants.STATUS_CODE_REJECTED)); 1303 } 1304 1305 @Test getUwbSession_success()1306 public void getUwbSession_success() { 1307 UwbSession mockUwbSession = mock(UwbSession.class); 1308 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1309 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1310 1311 UwbSession actualUwbSession = mUwbSessionManager.getUwbSession(TEST_SESSION_ID); 1312 1313 assertThat(actualUwbSession).isEqualTo(mockUwbSession); 1314 } 1315 1316 @Test getUwbSession_failed()1317 public void getUwbSession_failed() { 1318 UwbSession mockUwbSession = mock(UwbSession.class); 1319 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1320 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1321 1322 UwbSession actualUwbSession = mUwbSessionManager.getUwbSession(TEST_SESSION_ID - 1); 1323 1324 assertThat(actualUwbSession).isNull(); 1325 } 1326 1327 @Test getSessionId_success()1328 public void getSessionId_success() { 1329 UwbSession mockUwbSession = mock(UwbSession.class); 1330 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1331 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1332 mUwbSessionManager.mSessionTable.put(mockSessionHandle, mockUwbSession); 1333 when(mockUwbSession.getSessionHandle()).thenReturn(mockSessionHandle); 1334 1335 int actualSessionId = mUwbSessionManager.getSessionId(mockSessionHandle); 1336 1337 assertThat(actualSessionId).isEqualTo(TEST_SESSION_ID); 1338 } 1339 1340 @Test getSessionId_failed()1341 public void getSessionId_failed() { 1342 UwbSession mockUwbSession = mock(UwbSession.class); 1343 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1344 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1345 mUwbSessionManager.mSessionTable.put(mockSessionHandle, mockUwbSession); 1346 when(mockUwbSession.getSessionHandle()).thenReturn(mockSessionHandle); 1347 1348 Integer actualSessionId = mUwbSessionManager.getSessionId(mock(SessionHandle.class)); 1349 1350 assertThat(actualSessionId).isNull(); 1351 } 1352 1353 @Test isExistedSession_sessionHandle_success()1354 public void isExistedSession_sessionHandle_success() { 1355 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 1356 1357 boolean result = mUwbSessionManager.isExistedSession(mock(SessionHandle.class)); 1358 1359 assertThat(result).isTrue(); 1360 } 1361 1362 @Test iexExistedSession_sessionHandle_failed()1363 public void iexExistedSession_sessionHandle_failed() { 1364 doReturn(null).when(mUwbSessionManager).getSessionId(any()); 1365 1366 boolean result = mUwbSessionManager.isExistedSession(mock(SessionHandle.class)); 1367 1368 assertThat(result).isFalse(); 1369 } 1370 1371 @Test isExistedSession_sessionId_success()1372 public void isExistedSession_sessionId_success() { 1373 UwbSession mockUwbSession = mock(UwbSession.class); 1374 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1375 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1376 1377 boolean result = mUwbSessionManager.isExistedSession(TEST_SESSION_ID); 1378 1379 assertThat(result).isTrue(); 1380 } 1381 1382 @Test iexExistedSession_sessionId_failed()1383 public void iexExistedSession_sessionId_failed() { 1384 boolean result = mUwbSessionManager.isExistedSession(TEST_SESSION_ID); 1385 1386 assertThat(result).isFalse(); 1387 } 1388 1389 @Test stopAllRanging()1390 public void stopAllRanging() { 1391 UwbSession mockUwbSession1 = mock(UwbSession.class); 1392 when(mockUwbSession1.getSessionId()).thenReturn(TEST_SESSION_ID); 1393 when(mockUwbSession1.getChipId()).thenReturn(TEST_CHIP_ID); 1394 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession1); 1395 1396 UwbSession mockUwbSession2 = mock(UwbSession.class); 1397 when(mockUwbSession2.getSessionId()).thenReturn(TEST_SESSION_ID + 100); 1398 when(mockUwbSession2.getChipId()).thenReturn(TEST_CHIP_ID); 1399 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession2); 1400 1401 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 1402 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 1403 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID + 100), anyString())) 1404 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1405 1406 mUwbSessionManager.stopAllRanging(); 1407 1408 verify(mNativeUwbManager, times(2)) 1409 .stopRanging(anyInt(), anyString()); 1410 verify(mockUwbSession1, never()).setSessionState(anyInt()); 1411 verify(mockUwbSession2).setSessionState(eq(UwbUciConstants.UWB_SESSION_STATE_IDLE)); 1412 } 1413 1414 @Test setCurrentSessionState()1415 public void setCurrentSessionState() { 1416 UwbSession mockUwbSession = mock(UwbSession.class); 1417 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1418 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1419 1420 mUwbSessionManager.setCurrentSessionState( 1421 TEST_SESSION_ID, UwbUciConstants.UWB_SESSION_STATE_ACTIVE); 1422 1423 verify(mockUwbSession).setSessionState(eq(UwbUciConstants.UWB_SESSION_STATE_ACTIVE)); 1424 } 1425 1426 @Test getCurrentSessionState_nullSession()1427 public void getCurrentSessionState_nullSession() { 1428 int actualStatus = mUwbSessionManager.getCurrentSessionState(TEST_SESSION_ID); 1429 1430 assertThat(actualStatus).isEqualTo(UwbUciConstants.UWB_SESSION_STATE_ERROR); 1431 } 1432 1433 @Test getCurrentSessionState_success()1434 public void getCurrentSessionState_success() { 1435 UwbSession mockUwbSession = mock(UwbSession.class); 1436 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1437 when(mockUwbSession.getSessionState()).thenReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE); 1438 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1439 1440 int actualStatus = mUwbSessionManager.getCurrentSessionState(TEST_SESSION_ID); 1441 1442 assertThat(actualStatus).isEqualTo(UwbUciConstants.UWB_SESSION_STATE_ACTIVE); 1443 } 1444 1445 @Test getSessionIdSet()1446 public void getSessionIdSet() { 1447 UwbSession mockUwbSession = mock(UwbSession.class); 1448 when(mockUwbSession.getSessionId()).thenReturn(TEST_SESSION_ID); 1449 mUwbSessionManager.mSessionTable.put(mock(SessionHandle.class), mockUwbSession); 1450 1451 Set<Integer> actualSessionIds = mUwbSessionManager.getSessionIdSet(); 1452 1453 assertThat(actualSessionIds).hasSize(1); 1454 assertThat(actualSessionIds.contains(TEST_SESSION_ID)).isTrue(); 1455 } 1456 1457 @Test reconfigure_notExistedSession()1458 public void reconfigure_notExistedSession() { 1459 doReturn(false).when(mUwbSessionManager).isExistedSession(any()); 1460 1461 int actualStatus = mUwbSessionManager.reconfigure( 1462 mock(SessionHandle.class), mock(Params.class)); 1463 1464 assertThat(actualStatus).isEqualTo(UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST); 1465 } 1466 setUpUwbSessionForExecution(AttributionSource attributionSource)1467 private UwbSession setUpUwbSessionForExecution(AttributionSource attributionSource) { 1468 return setUpUwbSessionForExecution(attributionSource, setupFiraParams()); 1469 } 1470 setUpUwbSessionForExecution(AttributionSource attributionSource, Params params)1471 private UwbSession setUpUwbSessionForExecution(AttributionSource attributionSource, 1472 Params params) { 1473 // setup message 1474 doReturn(0).when(mUwbSessionManager).getSessionCount(); 1475 doReturn(0L).when(mUwbSessionManager).getFiraSessionCount(); 1476 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 1477 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 1478 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1479 IBinder mockBinder = mock(IBinder.class); 1480 UwbSession uwbSession = spy( 1481 mUwbSessionManager.new UwbSession(attributionSource, mockSessionHandle, 1482 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, params, 1483 mockRangingCallbacks, TEST_CHIP_ID)); 1484 doReturn(mockBinder).when(uwbSession).getBinder(); 1485 doReturn(uwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), anyInt(), 1486 anyByte(), anyString(), any(), any(), anyString()); 1487 doReturn(mock(WaitObj.class)).when(uwbSession).getWaitObj(); 1488 1489 return uwbSession; 1490 } 1491 setupFiraParams()1492 private Params setupFiraParams() { 1493 return setupFiraParams(FiraParams.RANGING_DEVICE_ROLE_INITIATOR, Optional.empty()); 1494 } 1495 setupFiraParams(int deviceRole, Optional<Integer> rangingRoundUsageOptional)1496 private Params setupFiraParams(int deviceRole, Optional<Integer> rangingRoundUsageOptional) { 1497 FiraOpenSessionParams.Builder paramsBuilder = new FiraOpenSessionParams.Builder() 1498 .setDeviceAddress(UwbAddress.fromBytes(new byte[] {(byte) 0x01, (byte) 0x02 })) 1499 .setVendorId(new byte[] { (byte) 0x00, (byte) 0x01 }) 1500 .setStaticStsIV(new byte[] { (byte) 0x01, (byte) 0x02, (byte) 0x03, 1501 (byte) 0x04, (byte) 0x05, (byte) 0x06 }) 1502 .setDestAddressList(Arrays.asList( 1503 UWB_DEST_ADDRESS)) 1504 .setProtocolVersion(new FiraProtocolVersion(1, 0)) 1505 .setSessionId(10) 1506 .setSessionType(SESSION_TYPE_RANGING) 1507 .setDeviceType(FiraParams.RANGING_DEVICE_TYPE_CONTROLLER) 1508 .setDeviceRole(deviceRole) 1509 .setMultiNodeMode(FiraParams.MULTI_NODE_MODE_UNICAST) 1510 .setRangingIntervalMs(TEST_RANGING_INTERVAL_MS); 1511 1512 if (rangingRoundUsageOptional.isPresent()) { 1513 paramsBuilder.setRangingRoundUsage(rangingRoundUsageOptional.get()); 1514 } 1515 1516 return paramsBuilder.build(); 1517 } 1518 setUpCccUwbSessionForExecution()1519 private UwbSession setUpCccUwbSessionForExecution() throws RemoteException { 1520 // setup message 1521 doReturn(0).when(mUwbSessionManager).getSessionCount(); 1522 doReturn(0L).when(mUwbSessionManager).getCccSessionCount(); 1523 doReturn(false).when(mUwbSessionManager).isExistedSession(anyInt()); 1524 IUwbRangingCallbacks mockRangingCallbacks = mock(IUwbRangingCallbacks.class); 1525 SessionHandle mockSessionHandle = mock(SessionHandle.class); 1526 Params params = new CccOpenRangingParams.Builder() 1527 .setProtocolVersion(CccParams.PROTOCOL_VERSION_1_0) 1528 .setUwbConfig(CccParams.UWB_CONFIG_0) 1529 .setPulseShapeCombo( 1530 new CccPulseShapeCombo( 1531 CccParams.PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE, 1532 CccParams.PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE)) 1533 .setSessionId(1) 1534 .setRanMultiplier(4) 1535 .setChannel(CccParams.UWB_CHANNEL_9) 1536 .setNumChapsPerSlot(CccParams.CHAPS_PER_SLOT_3) 1537 .setNumResponderNodes(1) 1538 .setNumSlotsPerRound(CccParams.SLOTS_PER_ROUND_6) 1539 .setSyncCodeIndex(1) 1540 .setHoppingConfigMode(CccParams.HOPPING_CONFIG_MODE_NONE) 1541 .setHoppingSequence(CccParams.HOPPING_SEQUENCE_DEFAULT) 1542 .build(); 1543 IBinder mockBinder = mock(IBinder.class); 1544 UwbSession uwbSession = spy( 1545 mUwbSessionManager.new UwbSession(ATTRIBUTION_SOURCE, mockSessionHandle, 1546 TEST_SESSION_ID, TEST_SESSION_TYPE, CccParams.PROTOCOL_NAME, params, 1547 mockRangingCallbacks, TEST_CHIP_ID)); 1548 doReturn(mockBinder).when(uwbSession).getBinder(); 1549 doReturn(uwbSession).when(mUwbSessionManager).createUwbSession(any(), any(), anyInt(), 1550 anyByte(), anyString(), any(), any(), anyString()); 1551 doReturn(mock(WaitObj.class)).when(uwbSession).getWaitObj(); 1552 1553 return uwbSession; 1554 } 1555 1556 @Test openRanging_success()1557 public void openRanging_success() throws Exception { 1558 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1559 // stub for openRanging conditions 1560 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1561 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1562 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1563 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1564 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1565 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 1566 1567 1568 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1569 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1570 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1571 mTestLooper.dispatchAll(); 1572 1573 verify(mNativeUwbManager).initSession(eq(TEST_SESSION_ID), anyByte(), eq(TEST_CHIP_ID)); 1574 verify(mUwbConfigurationManager) 1575 .setAppConfigurations(eq(TEST_SESSION_ID), any(), eq(TEST_CHIP_ID)); 1576 verify(mUwbSessionNotificationManager).onRangingOpened(eq(uwbSession)); 1577 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1578 eq(UwbUciConstants.STATUS_CODE_OK)); 1579 } 1580 1581 @Test openRanging_timeout()1582 public void openRanging_timeout() throws Exception { 1583 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1584 // stub for openRanging conditions 1585 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1586 .thenThrow(new IllegalStateException()); 1587 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1588 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1589 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1590 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 1591 1592 1593 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1594 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1595 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1596 mTestLooper.dispatchAll(); 1597 1598 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1599 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1600 verify(mUwbSessionNotificationManager) 1601 .onRangingOpenFailed(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 1602 verify(mNativeUwbManager).deInitSession(eq(TEST_SESSION_ID), eq(TEST_CHIP_ID)); 1603 } 1604 1605 @Test openRanging_nativeInitSessionFailed()1606 public void openRanging_nativeInitSessionFailed() throws Exception { 1607 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1608 // stub for openRanging conditions 1609 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1610 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 1611 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1612 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1613 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1614 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 1615 1616 1617 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1618 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1619 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1620 mTestLooper.dispatchAll(); 1621 1622 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1623 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1624 verify(mUwbSessionNotificationManager) 1625 .onRangingOpenFailed(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 1626 verify(mNativeUwbManager).deInitSession(eq(TEST_SESSION_ID), eq(TEST_CHIP_ID)); 1627 } 1628 1629 @Test openRanging_setAppConfigurationFailed()1630 public void openRanging_setAppConfigurationFailed() throws Exception { 1631 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1632 // stub for openRanging conditions 1633 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1634 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1635 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1636 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1637 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1638 .thenReturn(UwbUciConstants.STATUS_CODE_FAILED); 1639 1640 1641 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1642 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1643 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1644 mTestLooper.dispatchAll(); 1645 1646 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1647 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1648 verify(mUwbSessionNotificationManager) 1649 .onRangingOpenFailed(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 1650 verify(mNativeUwbManager).deInitSession(eq(TEST_SESSION_ID), eq(TEST_CHIP_ID)); 1651 } 1652 1653 @Test openRanging_wrongInitState()1654 public void openRanging_wrongInitState() throws Exception { 1655 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1656 // stub for openRanging conditions 1657 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1658 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1659 doReturn(UwbUciConstants.UWB_SESSION_STATE_ERROR, 1660 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1661 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1662 .thenReturn(UwbUciConstants.STATUS_CODE_FAILED); 1663 1664 1665 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1666 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1667 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1668 mTestLooper.dispatchAll(); 1669 1670 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1671 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1672 verify(mUwbSessionNotificationManager) 1673 .onRangingOpenFailed(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 1674 verify(mNativeUwbManager).deInitSession(eq(TEST_SESSION_ID), eq(TEST_CHIP_ID)); 1675 } 1676 1677 @Test openRanging_wrongIdleState()1678 public void openRanging_wrongIdleState() throws Exception { 1679 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1680 // stub for openRanging conditions 1681 when(mNativeUwbManager.initSession(anyInt(), anyByte(), anyString())) 1682 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1683 doReturn(UwbUciConstants.UWB_SESSION_STATE_INIT, 1684 UwbUciConstants.UWB_SESSION_STATE_ERROR).when(uwbSession).getSessionState(); 1685 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 1686 .thenReturn(UwbUciConstants.STATUS_CODE_FAILED); 1687 1688 1689 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1690 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1691 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1692 mTestLooper.dispatchAll(); 1693 1694 verify(mUwbMetrics).logRangingInitEvent(eq(uwbSession), 1695 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1696 verify(mUwbSessionNotificationManager) 1697 .onRangingOpenFailed(eq(uwbSession), 1698 eq(UwbUciConstants.STATUS_CODE_FAILED)); 1699 verify(mNativeUwbManager).deInitSession(eq(TEST_SESSION_ID), eq(TEST_CHIP_ID)); 1700 } 1701 1702 @Test testInitSessionWithNonSystemAppInFg()1703 public void testInitSessionWithNonSystemAppInFg() throws Exception { 1704 when(mUwbInjector.isSystemApp(UID, PACKAGE_NAME)).thenReturn(false); 1705 when(mUwbInjector.isForegroundAppOrService(UID, PACKAGE_NAME)).thenReturn(true); 1706 1707 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1708 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1709 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1710 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1711 1712 // OPEN_RANGING message scheduled. 1713 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1714 assertThat(mTestLooper.isIdle()).isFalse(); 1715 } 1716 1717 @Test testInitSessionWithNonSystemAppNotInFg()1718 public void testInitSessionWithNonSystemAppNotInFg() throws Exception { 1719 when(mUwbInjector.isSystemApp(UID, PACKAGE_NAME)).thenReturn(false); 1720 when(mUwbInjector.isForegroundAppOrService(UID, PACKAGE_NAME)).thenReturn(false); 1721 1722 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1723 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1724 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1725 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1726 1727 verify(uwbSession.getIUwbRangingCallbacks()).onRangingOpenFailed( 1728 eq(uwbSession.getSessionHandle()), eq(StateChangeReason.SYSTEM_POLICY), any()); 1729 // No OPEN_RANGING message scheduled. 1730 assertThat(mTestLooper.isIdle()).isFalse(); 1731 } 1732 1733 @Test testInitSessionWithNonSystemAppNotInFg_WhenBgRangingEnabled()1734 public void testInitSessionWithNonSystemAppNotInFg_WhenBgRangingEnabled() throws Exception { 1735 when(mDeviceConfigFacade.isBackgroundRangingEnabled()).thenReturn(true); 1736 when(mUwbInjector.isSystemApp(UID, PACKAGE_NAME)).thenReturn(false); 1737 when(mUwbInjector.isForegroundAppOrService(UID, PACKAGE_NAME)).thenReturn(false); 1738 1739 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1740 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1741 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1742 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1743 1744 // OPEN_RANGING message scheduled. 1745 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1746 assertThat(mTestLooper.isIdle()).isFalse(); 1747 } 1748 initUwbSessionForNonSystemAppInFgInChain()1749 private UwbSession initUwbSessionForNonSystemAppInFgInChain() throws Exception { 1750 when(mUwbInjector.isSystemApp(UID_2, PACKAGE_NAME_2)).thenReturn(false); 1751 when(mUwbInjector.isForegroundAppOrService(UID_2, PACKAGE_NAME_2)) 1752 .thenReturn(true); 1753 1754 // simulate system app triggered the request on behalf of a fg app in fg. 1755 AttributionSource attributionSource = new AttributionSource.Builder(UID) 1756 .setPackageName(PACKAGE_NAME) 1757 .setNext(new AttributionSource.Builder(UID_2) 1758 .setPackageName(PACKAGE_NAME_2) 1759 .build()) 1760 .build(); 1761 1762 UwbSession uwbSession = setUpUwbSessionForExecution(attributionSource); 1763 mUwbSessionManager.initSession(attributionSource, uwbSession.getSessionHandle(), 1764 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1765 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1766 return uwbSession; 1767 } 1768 1769 @Test testOpenRangingWithNonSystemAppInFgInChain()1770 public void testOpenRangingWithNonSystemAppInFgInChain() throws Exception { 1771 initUwbSessionForNonSystemAppInFgInChain(); 1772 1773 // OPEN_RANGING message scheduled. 1774 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1775 assertThat(mTestLooper.isIdle()).isFalse(); 1776 } 1777 1778 @Test testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndStayThere()1779 public void testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndStayThere() throws Exception { 1780 UwbSession uwbSession = initUwbSessionForNonSystemAppInFgInChain(); 1781 1782 // Verify that an OPEN_RANGING message was scheduled. 1783 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1784 1785 // Start Ranging 1786 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 1787 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1788 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, 1789 UwbUciConstants.UWB_SESSION_STATE_ACTIVE).when(uwbSession).getSessionState(); 1790 mUwbSessionManager.startRanging( 1791 uwbSession.getSessionHandle(), uwbSession.getParams()); 1792 mTestLooper.dispatchAll(); 1793 1794 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 1795 verify(mUwbMetrics).longRangingStartEvent( 1796 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 1797 1798 // Move the non-privileged app to background, this should result in the session getting 1799 // reconfigured (to disable the ranging data notifications). 1800 mOnUidImportanceListenerArgumentCaptor.getValue().onUidImportance( 1801 UID_2, IMPORTANCE_BACKGROUND); 1802 mTestLooper.dispatchAll(); 1803 ArgumentCaptor<Params> paramsArgumentCaptor = ArgumentCaptor.forClass(Params.class); 1804 verify(mUwbConfigurationManager).setAppConfigurations( 1805 eq(TEST_SESSION_ID), paramsArgumentCaptor.capture(), eq(TEST_CHIP_ID)); 1806 FiraRangingReconfigureParams firaParams = 1807 (FiraRangingReconfigureParams) paramsArgumentCaptor.getValue(); 1808 assertThat(firaParams.getRangeDataNtfConfig()).isEqualTo( 1809 FiraParams.RANGE_DATA_NTF_CONFIG_DISABLE); 1810 verify(mUwbSessionNotificationManager, never()).onRangingReconfigured(eq(uwbSession)); 1811 1812 // Verify the appropriate timer is setup. 1813 ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = 1814 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 1815 verify(mAlarmManager).setExact( 1816 anyInt(), anyLong(), eq(UwbSession.NON_PRIVILEGED_BG_APP_TIMER_TAG), 1817 alarmListenerCaptor.capture(), any()); 1818 assertThat(alarmListenerCaptor.getValue()).isNotNull(); 1819 1820 // Now fire the timer callback. 1821 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, 1822 UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1823 alarmListenerCaptor.getValue().onAlarm(); 1824 1825 // Expect session stop. 1826 mTestLooper.dispatchAll(); 1827 verify(mUwbSessionNotificationManager).onRangingStoppedWithApiReasonCode( 1828 eq(uwbSession), eq(RangingChangeReason.SYSTEM_POLICY)); 1829 verify(mUwbMetrics).longRangingStopEvent(eq(uwbSession)); 1830 } 1831 1832 @Test 1833 public void testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndStayThere_WhenBgRangingEnabled()1834 testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndStayThere_WhenBgRangingEnabled() 1835 throws Exception { 1836 when(mDeviceConfigFacade.isBackgroundRangingEnabled()).thenReturn(true); 1837 UwbSession uwbSession = initUwbSessionForNonSystemAppInFgInChain(); 1838 1839 // Verify that an OPEN_RANGING message was scheduled. 1840 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1841 1842 // Start Ranging 1843 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 1844 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1845 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, 1846 UwbUciConstants.UWB_SESSION_STATE_ACTIVE).when(uwbSession).getSessionState(); 1847 mUwbSessionManager.startRanging( 1848 uwbSession.getSessionHandle(), uwbSession.getParams()); 1849 mTestLooper.dispatchAll(); 1850 1851 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 1852 verify(mUwbMetrics).longRangingStartEvent( 1853 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 1854 1855 // Move the non-privileged app to background, this should result in the session getting 1856 // reconfigured (to disable the ranging data notifications). 1857 mOnUidImportanceListenerArgumentCaptor.getValue().onUidImportance( 1858 UID_2, IMPORTANCE_BACKGROUND); 1859 mTestLooper.dispatchAll(); 1860 ArgumentCaptor<Params> paramsArgumentCaptor = ArgumentCaptor.forClass(Params.class); 1861 verify(mUwbConfigurationManager).setAppConfigurations( 1862 eq(TEST_SESSION_ID), paramsArgumentCaptor.capture(), eq(TEST_CHIP_ID)); 1863 FiraRangingReconfigureParams firaParams = 1864 (FiraRangingReconfigureParams) paramsArgumentCaptor.getValue(); 1865 assertThat(firaParams.getRangeDataNtfConfig()).isEqualTo( 1866 FiraParams.RANGE_DATA_NTF_CONFIG_DISABLE); 1867 verify(mUwbSessionNotificationManager, never()).onRangingReconfigured(eq(uwbSession)); 1868 1869 // Verify the timer is not setup. 1870 verify(mAlarmManager, never()).setExact( 1871 anyInt(), anyLong(), eq(UwbSession.NON_PRIVILEGED_BG_APP_TIMER_TAG), 1872 any(), any()); 1873 } 1874 1875 @Test testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndFg()1876 public void testOpenRangingWithNonSystemAppInFgInChain_MoveToBgAndFg() throws Exception { 1877 UwbSession uwbSession = initUwbSessionForNonSystemAppInFgInChain(); 1878 // OPEN_RANGING message scheduled. 1879 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1880 mTestLooper.dispatchAll(); 1881 1882 // Move to background. 1883 mOnUidImportanceListenerArgumentCaptor.getValue().onUidImportance( 1884 UID_2, IMPORTANCE_BACKGROUND); 1885 mTestLooper.dispatchAll(); 1886 ArgumentCaptor<Params> paramsArgumentCaptor = ArgumentCaptor.forClass(Params.class); 1887 verify(mUwbConfigurationManager).setAppConfigurations( 1888 eq(TEST_SESSION_ID), paramsArgumentCaptor.capture(), eq(TEST_CHIP_ID)); 1889 FiraRangingReconfigureParams firaParams = 1890 (FiraRangingReconfigureParams) paramsArgumentCaptor.getValue(); 1891 assertThat(firaParams.getRangeDataNtfConfig()).isEqualTo( 1892 FiraParams.RANGE_DATA_NTF_CONFIG_DISABLE); 1893 verify(mUwbSessionNotificationManager, never()).onRangingReconfigured(eq(uwbSession)); 1894 1895 // Move to foreground. 1896 mOnUidImportanceListenerArgumentCaptor.getValue().onUidImportance( 1897 UID_2, IMPORTANCE_FOREGROUND); 1898 mTestLooper.dispatchAll(); 1899 paramsArgumentCaptor = ArgumentCaptor.forClass(Params.class); 1900 verify(mUwbConfigurationManager, times(2)).setAppConfigurations( 1901 eq(TEST_SESSION_ID), paramsArgumentCaptor.capture(), eq(TEST_CHIP_ID)); 1902 firaParams = (FiraRangingReconfigureParams) paramsArgumentCaptor.getValue(); 1903 assertThat(firaParams.getRangeDataNtfConfig()).isEqualTo( 1904 FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE); 1905 verify(mUwbSessionNotificationManager, never()).onRangingReconfigured(eq(uwbSession)); 1906 } 1907 1908 @Test testOpenRangingWithNonSystemAppInFgInChain_MoveToBgTriggersSessionPriorityChange()1909 public void testOpenRangingWithNonSystemAppInFgInChain_MoveToBgTriggersSessionPriorityChange() 1910 throws Exception { 1911 UwbSession uwbSession = initUwbSessionForNonSystemAppInFgInChain(); 1912 1913 assertThat(uwbSession.getStackSessionPriority()).isEqualTo(UwbSession.FG_SESSION_PRIORITY); 1914 assertThat(mTestLooper.nextMessage().what).isEqualTo(SESSION_OPEN_RANGING); 1915 mTestLooper.dispatchAll(); 1916 1917 // Move to background. 1918 when(mUwbInjector.isForegroundAppOrService(UID_2, PACKAGE_NAME_2)) 1919 .thenReturn(false); 1920 mOnUidImportanceListenerArgumentCaptor.getValue().onUidImportance( 1921 UID_2, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED); 1922 mTestLooper.dispatchAll(); 1923 1924 assertThat(uwbSession.getStackSessionPriority()).isEqualTo(UwbSession.BG_SESSION_PRIORITY); 1925 } 1926 1927 @Test testOpenRangingWithNonSystemAppNotInFgInChain()1928 public void testOpenRangingWithNonSystemAppNotInFgInChain() throws Exception { 1929 when(mUwbInjector.isSystemApp(UID_2, PACKAGE_NAME_2)).thenReturn(false); 1930 when(mUwbInjector.isForegroundAppOrService(UID_2, PACKAGE_NAME_2)) 1931 .thenReturn(false); 1932 1933 // simulate system app triggered the request on behalf of a fg app not in fg. 1934 AttributionSource attributionSource = new AttributionSource.Builder(UID) 1935 .setPackageName(PACKAGE_NAME) 1936 .setNext(new AttributionSource.Builder(UID_2) 1937 .setPackageName(PACKAGE_NAME_2) 1938 .build()) 1939 .build(); 1940 UwbSession uwbSession = setUpUwbSessionForExecution(attributionSource); 1941 mUwbSessionManager.initSession(attributionSource, uwbSession.getSessionHandle(), 1942 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1943 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1944 1945 verify(uwbSession.getIUwbRangingCallbacks()).onRangingOpenFailed( 1946 eq(uwbSession.getSessionHandle()), eq(StateChangeReason.SYSTEM_POLICY), any()); 1947 // No OPEN_RANGING message scheduled. 1948 assertThat(mTestLooper.isIdle()).isFalse(); 1949 } 1950 prepareExistingUwbSessionCommon(UwbSession uwbSession)1951 private UwbSession prepareExistingUwbSessionCommon(UwbSession uwbSession) throws Exception { 1952 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1953 TEST_SESSION_ID, TEST_SESSION_TYPE, FiraParams.PROTOCOL_NAME, 1954 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1955 mTestLooper.nextMessage(); // remove the OPEN_RANGING msg; 1956 1957 assertThat(mTestLooper.isIdle()).isFalse(); 1958 1959 return uwbSession; 1960 } prepareExistingUwbSession(Params params)1961 private UwbSession prepareExistingUwbSession(Params params) throws Exception { 1962 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE, params); 1963 return prepareExistingUwbSessionCommon(uwbSession); 1964 } prepareExistingUwbSession()1965 private UwbSession prepareExistingUwbSession() throws Exception { 1966 UwbSession uwbSession = setUpUwbSessionForExecution(ATTRIBUTION_SOURCE); 1967 return prepareExistingUwbSessionCommon(uwbSession); 1968 } 1969 prepareExistingUwbSessionActive()1970 private UwbSession prepareExistingUwbSessionActive() throws Exception { 1971 UwbSession uwbSession = prepareExistingUwbSession(); 1972 1973 // Setup the UwbSession to start ranging (and move it to active state). 1974 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 1975 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 1976 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 1977 1978 mUwbSessionManager.startRanging(uwbSession.getSessionHandle(), uwbSession.getParams()); 1979 mTestLooper.dispatchAll(); 1980 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE).when(uwbSession).getSessionState(); 1981 1982 return uwbSession; 1983 } 1984 prepareExistingCccUwbSession()1985 private UwbSession prepareExistingCccUwbSession() throws Exception { 1986 UwbSession uwbSession = setUpCccUwbSessionForExecution(); 1987 mUwbSessionManager.initSession(ATTRIBUTION_SOURCE, uwbSession.getSessionHandle(), 1988 TEST_SESSION_ID, TEST_SESSION_TYPE, CccParams.PROTOCOL_NAME, 1989 uwbSession.getParams(), uwbSession.getIUwbRangingCallbacks(), TEST_CHIP_ID); 1990 mTestLooper.nextMessage(); // remove the OPEN_RANGING msg; 1991 1992 assertThat(mTestLooper.isIdle()).isFalse(); 1993 1994 return uwbSession; 1995 } 1996 1997 @Test reconfigure_calledSuccess()1998 public void reconfigure_calledSuccess() throws Exception { 1999 UwbSession uwbSession = prepareExistingUwbSession(); 2000 FiraRangingReconfigureParams params = 2001 new FiraRangingReconfigureParams.Builder() 2002 .setBlockStrideLength(10) 2003 .setRangeDataNtfConfig(1) 2004 .setRangeDataProximityFar(10) 2005 .setRangeDataProximityNear(2) 2006 .build(); 2007 2008 int actualStatus = mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), params); 2009 2010 assertThat(actualStatus).isEqualTo(0); 2011 assertThat(mTestLooper.nextMessage().what) 2012 .isEqualTo(UwbSessionManager.SESSION_RECONFIG_RANGING); 2013 2014 // Verify the cache has been updated. 2015 FiraOpenSessionParams firaParams = (FiraOpenSessionParams) uwbSession.getParams(); 2016 assertThat(firaParams.getBlockStrideLength()).isEqualTo(10); 2017 assertThat(firaParams.getRangeDataNtfConfig()).isEqualTo(1); 2018 assertThat(firaParams.getRangeDataNtfProximityFar()).isEqualTo(10); 2019 assertThat(firaParams.getRangeDataNtfProximityNear()).isEqualTo(2); 2020 } 2021 2022 @Test startRanging_sessionStateIdle()2023 public void startRanging_sessionStateIdle() throws Exception { 2024 UwbSession uwbSession = prepareExistingUwbSession(); 2025 // set up for start ranging 2026 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE) 2027 .when(uwbSession).getSessionState(); 2028 2029 mUwbSessionManager.startRanging( 2030 uwbSession.getSessionHandle(), uwbSession.getParams()); 2031 2032 assertThat(mTestLooper.isIdle()).isTrue(); 2033 assertThat(mTestLooper.nextMessage().what).isEqualTo(2); // SESSION_START_RANGING 2034 } 2035 2036 @Test startRanging_sessionStateActive()2037 public void startRanging_sessionStateActive() throws Exception { 2038 UwbSession uwbSession = prepareExistingUwbSession(); 2039 // set up for start ranging 2040 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2041 .when(uwbSession).getSessionState(); 2042 2043 mUwbSessionManager.startRanging( 2044 uwbSession.getSessionHandle(), uwbSession.getParams()); 2045 2046 assertThat(mTestLooper.isIdle()).isFalse(); 2047 verify(mUwbSessionNotificationManager).onRangingStartFailed( 2048 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_REJECTED)); 2049 } 2050 2051 @Test startRanging_sessionStateError()2052 public void startRanging_sessionStateError() throws Exception { 2053 UwbSession uwbSession = prepareExistingUwbSession(); 2054 // set up for start ranging 2055 doReturn(UwbUciConstants.UWB_SESSION_STATE_ERROR) 2056 .when(uwbSession).getSessionState(); 2057 2058 mUwbSessionManager.startRanging( 2059 uwbSession.getSessionHandle(), uwbSession.getParams()); 2060 2061 assertThat(mTestLooper.isIdle()).isFalse(); 2062 verify(mUwbSessionNotificationManager).onRangingStartFailed( 2063 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2064 verify(mUwbMetrics).longRangingStartEvent( 2065 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2066 } 2067 2068 @Test execStartRanging_success()2069 public void execStartRanging_success() throws Exception { 2070 UwbSession uwbSession = prepareExistingUwbSession(); 2071 // set up for start ranging 2072 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2073 .when(uwbSession).getSessionState(); 2074 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2075 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2076 2077 mUwbSessionManager.startRanging( 2078 uwbSession.getSessionHandle(), uwbSession.getParams()); 2079 mTestLooper.dispatchAll(); 2080 2081 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 2082 verify(mUwbMetrics).longRangingStartEvent( 2083 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2084 } 2085 2086 @Test execStartRanging_onRangeDataNotification()2087 public void execStartRanging_onRangeDataNotification() throws Exception { 2088 UwbSession uwbSession = prepareExistingUwbSession(); 2089 // set up for start ranging 2090 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2091 .when(uwbSession).getSessionState(); 2092 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2093 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2094 2095 mUwbSessionManager.startRanging( 2096 uwbSession.getSessionHandle(), uwbSession.getParams()); 2097 mTestLooper.dispatchAll(); 2098 2099 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 2100 verify(mUwbMetrics).longRangingStartEvent( 2101 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2102 2103 // Now send a range data notification. 2104 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 2105 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 2106 UwbUciConstants.STATUS_CODE_OK); 2107 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2108 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2109 } 2110 2111 @Test execStartRanging_twoWay_onRangeDataNotificationContinuousErrors()2112 public void execStartRanging_twoWay_onRangeDataNotificationContinuousErrors() throws Exception { 2113 startRanging_onRangeDataNotificationContinuousErrors(RANGING_MEASUREMENT_TYPE_TWO_WAY); 2114 } 2115 2116 @Test execStartRanging_owrAoa_onRangeDataNotificationContinuousErrors()2117 public void execStartRanging_owrAoa_onRangeDataNotificationContinuousErrors() throws Exception { 2118 startRanging_onRangeDataNotificationContinuousErrors(RANGING_MEASUREMENT_TYPE_OWR_AOA); 2119 } 2120 startRanging_onRangeDataNotificationContinuousErrors( int rangingMeasurementType)2121 private void startRanging_onRangeDataNotificationContinuousErrors( 2122 int rangingMeasurementType) throws Exception { 2123 UwbSession uwbSession = prepareExistingUwbSession(); 2124 // set up for start ranging 2125 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2126 .when(uwbSession).getSessionState(); 2127 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2128 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2129 2130 mUwbSessionManager.startRanging( 2131 uwbSession.getSessionHandle(), uwbSession.getParams()); 2132 mTestLooper.dispatchAll(); 2133 2134 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 2135 verify(mUwbMetrics).longRangingStartEvent( 2136 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2137 2138 // Now send a range data notification with an error. 2139 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 2140 rangingMeasurementType, MAC_ADDRESSING_MODE_EXTENDED, 2141 UwbUciConstants.STATUS_CODE_RANGING_RX_TIMEOUT); 2142 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2143 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2144 ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = 2145 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 2146 verify(mAlarmManager).setExact( 2147 anyInt(), anyLong(), anyString(), alarmListenerCaptor.capture(), any()); 2148 assertThat(alarmListenerCaptor.getValue()).isNotNull(); 2149 2150 // Send one more error and ensure that the timer is not cancelled. 2151 uwbRangingData = UwbTestUtils.generateRangingData( 2152 rangingMeasurementType, MAC_ADDRESSING_MODE_EXTENDED, 2153 UwbUciConstants.STATUS_CODE_RANGING_RX_TIMEOUT); 2154 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2155 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2156 2157 verify(mAlarmManager, never()).cancel(any(AlarmManager.OnAlarmListener.class)); 2158 2159 // set up for stop ranging 2160 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, UwbUciConstants.UWB_SESSION_STATE_IDLE) 2161 .when(uwbSession).getSessionState(); 2162 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 2163 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2164 2165 // Now fire the timer callback. 2166 alarmListenerCaptor.getValue().onAlarm(); 2167 2168 // Expect session stop. 2169 mTestLooper.dispatchNext(); 2170 verify(mUwbSessionNotificationManager) 2171 .onRangingStoppedWithApiReasonCode(eq(uwbSession), 2172 eq(RangingChangeReason.SYSTEM_POLICY)); 2173 verify(mUwbMetrics).longRangingStopEvent(eq(uwbSession)); 2174 } 2175 2176 @Test 2177 public void execStartRanging_onRangeDataNotificationContinuousErrors_WhenErrorStreakTimerDisabled()2178 execStartRanging_onRangeDataNotificationContinuousErrors_WhenErrorStreakTimerDisabled() 2179 throws Exception { 2180 when(mDeviceConfigFacade.isRangingErrorStreakTimerEnabled()).thenReturn(false); 2181 2182 UwbSession uwbSession = prepareExistingUwbSession(); 2183 // set up for start ranging 2184 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2185 .when(uwbSession).getSessionState(); 2186 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2187 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2188 2189 mUwbSessionManager.startRanging( 2190 uwbSession.getSessionHandle(), uwbSession.getParams()); 2191 mTestLooper.dispatchAll(); 2192 2193 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 2194 verify(mUwbMetrics).longRangingStartEvent( 2195 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2196 2197 // Now send a range data notification with an error. 2198 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 2199 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 2200 UwbUciConstants.STATUS_CODE_RANGING_RX_TIMEOUT); 2201 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2202 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2203 // Ensure error streak timer is not started. 2204 verify(mAlarmManager, never()).setExact( 2205 anyInt(), anyLong(), anyString(), any(), any()); 2206 } 2207 2208 @Test execStartRanging_onRangeDataNotificationErrorFollowedBySuccess()2209 public void execStartRanging_onRangeDataNotificationErrorFollowedBySuccess() throws Exception { 2210 UwbSession uwbSession = prepareExistingUwbSession(); 2211 // set up for start ranging 2212 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2213 .when(uwbSession).getSessionState(); 2214 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2215 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2216 2217 mUwbSessionManager.startRanging( 2218 uwbSession.getSessionHandle(), uwbSession.getParams()); 2219 mTestLooper.dispatchAll(); 2220 2221 verify(mUwbSessionNotificationManager).onRangingStarted(eq(uwbSession), any()); 2222 verify(mUwbMetrics).longRangingStartEvent( 2223 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2224 2225 // Now send a range data notification with an error. 2226 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 2227 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 2228 UwbUciConstants.STATUS_CODE_RANGING_RX_TIMEOUT); 2229 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2230 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2231 ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = 2232 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 2233 verify(mAlarmManager).setExact( 2234 anyInt(), anyLong(), anyString(), alarmListenerCaptor.capture(), any()); 2235 assertThat(alarmListenerCaptor.getValue()).isNotNull(); 2236 2237 // Send success and ensure that the timer is cancelled. 2238 uwbRangingData = UwbTestUtils.generateRangingData( 2239 RANGING_MEASUREMENT_TYPE_TWO_WAY, MAC_ADDRESSING_MODE_EXTENDED, 2240 UwbUciConstants.STATUS_CODE_OK); 2241 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 2242 verify(mUwbSessionNotificationManager).onRangingResult(uwbSession, uwbRangingData); 2243 2244 verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class)); 2245 } 2246 2247 @Test session_receivedDataInfo()2248 public void session_receivedDataInfo() throws Exception { 2249 UwbSession uwbSession = prepareExistingUwbSession(); 2250 2251 // Setup the UwbSession to have multiple data packets (being received) for multiple remote 2252 // devices. This includes some duplicate packets (same sequence number from same remote 2253 // device), which should be ignored. 2254 UwbSessionManager.ReceivedDataInfo deviceOnePacketOne = buildReceivedDataInfo( 2255 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM); 2256 UwbSessionManager.ReceivedDataInfo deviceOnePacketTwo = buildReceivedDataInfo( 2257 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM_1); 2258 UwbSessionManager.ReceivedDataInfo deviceTwoPacketOne = buildReceivedDataInfo( 2259 PEER_EXTENDED_MAC_ADDRESS_2_LONG, DATA_SEQUENCE_NUM); 2260 UwbSessionManager.ReceivedDataInfo deviceTwoPacketTwo = buildReceivedDataInfo( 2261 PEER_EXTENDED_MAC_ADDRESS_2_LONG, DATA_SEQUENCE_NUM_1); 2262 when(mDeviceConfigFacade.getRxDataMaxPacketsToStore()) 2263 .thenReturn(MAX_RX_DATA_PACKETS_TO_STORE); 2264 2265 uwbSession.addReceivedDataInfo(deviceOnePacketOne); 2266 uwbSession.addReceivedDataInfo(deviceOnePacketTwo); 2267 uwbSession.addReceivedDataInfo(deviceOnePacketOne); 2268 2269 uwbSession.addReceivedDataInfo(deviceTwoPacketOne); 2270 uwbSession.addReceivedDataInfo(deviceTwoPacketTwo); 2271 uwbSession.addReceivedDataInfo(deviceTwoPacketOne); 2272 2273 // Verify that the first call to getAllReceivedDataInfo() for a device returns all it's 2274 // received packets, and the second call receives an empty list. 2275 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2276 List.of(deviceOnePacketOne, deviceOnePacketTwo)); 2277 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2278 List.of()); 2279 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_2_LONG)).isEqualTo( 2280 List.of(deviceTwoPacketOne, deviceTwoPacketTwo)); 2281 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_2_LONG)).isEqualTo( 2282 List.of()); 2283 } 2284 2285 @Test session_receivedDataInfo_maxCapacity()2286 public void session_receivedDataInfo_maxCapacity() throws Exception { 2287 UwbSession uwbSession = prepareExistingUwbSession(); 2288 2289 UwbSessionManager.ReceivedDataInfo rxPacketOne = buildReceivedDataInfo( 2290 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM + 1); 2291 UwbSessionManager.ReceivedDataInfo rxPacketTwo = buildReceivedDataInfo( 2292 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM + 2); 2293 UwbSessionManager.ReceivedDataInfo rxPacketThree = buildReceivedDataInfo( 2294 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM + 3); 2295 UwbSessionManager.ReceivedDataInfo rxPacketFour = buildReceivedDataInfo( 2296 PEER_EXTENDED_MAC_ADDRESS_LONG, DATA_SEQUENCE_NUM + 4); 2297 2298 // Setup the UwbSession to have multiple data packets (being received) from one remote 2299 // device, such that it's at the capacity. We send the packets out-of-order, but do want 2300 // to extract them in order. 2301 when(mDeviceConfigFacade.getRxDataMaxPacketsToStore()).thenReturn(3); 2302 2303 // Case 1 - Setup the UwbSession to have multiple Rx data packets (beyond capacity), such 2304 // that the last packet is the smallest one and should be dropped. 2305 uwbSession.addReceivedDataInfo(rxPacketTwo); 2306 uwbSession.addReceivedDataInfo(rxPacketFour); 2307 uwbSession.addReceivedDataInfo(rxPacketThree); 2308 uwbSession.addReceivedDataInfo(rxPacketOne); 2309 2310 // Verify that the first call to getAllReceivedDataInfo() returns the max capacity number of 2311 // packets (in-order), and the second call receives an empty list. 2312 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2313 List.of(rxPacketTwo, rxPacketThree, rxPacketFour)); 2314 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2315 List.of()); 2316 2317 // Case 2 - Setup the UwbSession to have multiple Rx data packets (beyond capacity), such 2318 // that one of the stored packets is the smallest one and should be dropped. 2319 uwbSession.addReceivedDataInfo(rxPacketOne); 2320 uwbSession.addReceivedDataInfo(rxPacketTwo); 2321 uwbSession.addReceivedDataInfo(rxPacketFour); 2322 uwbSession.addReceivedDataInfo(rxPacketThree); 2323 2324 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2325 List.of(rxPacketTwo, rxPacketThree, rxPacketFour)); 2326 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2327 List.of()); 2328 2329 // Case 3 - Setup the UwbSession to have multiple Rx data packets (beyond capacity), such 2330 // that one of the stored packets is repeated. The repeated packet should be ignored. 2331 uwbSession.addReceivedDataInfo(rxPacketTwo); 2332 uwbSession.addReceivedDataInfo(rxPacketFour); 2333 uwbSession.addReceivedDataInfo(rxPacketThree); 2334 uwbSession.addReceivedDataInfo(rxPacketFour); 2335 2336 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2337 List.of(rxPacketTwo, rxPacketThree, rxPacketFour)); 2338 assertThat(uwbSession.getAllReceivedDataInfo(PEER_EXTENDED_MAC_ADDRESS_LONG)).isEqualTo( 2339 List.of()); 2340 } 2341 2342 @Test execStartCccRanging_success()2343 public void execStartCccRanging_success() throws Exception { 2344 UwbSession uwbSession = prepareExistingCccUwbSession(); 2345 // set up for start ranging 2346 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2347 .when(uwbSession).getSessionState(); 2348 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2349 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2350 CccStartRangingParams cccStartRangingParams = new CccStartRangingParams.Builder() 2351 .setSessionId(TEST_SESSION_ID) 2352 .setRanMultiplier(8) 2353 .build(); 2354 mUwbSessionManager.startRanging( 2355 uwbSession.getSessionHandle(), cccStartRangingParams); 2356 mTestLooper.dispatchAll(); 2357 2358 // Verify the update logic. 2359 CccOpenRangingParams cccOpenRangingParams = (CccOpenRangingParams) uwbSession.getParams(); 2360 assertThat(cccOpenRangingParams.getRanMultiplier()).isEqualTo(8); 2361 } 2362 2363 @Test execStartCccRangingWithNoStartParams_success()2364 public void execStartCccRangingWithNoStartParams_success() throws Exception { 2365 UwbSession uwbSession = prepareExistingCccUwbSession(); 2366 // set up for start ranging 2367 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2368 .when(uwbSession).getSessionState(); 2369 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2370 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2371 mUwbSessionManager.startRanging(uwbSession.getSessionHandle(), null /* params */); 2372 mTestLooper.dispatchAll(); 2373 2374 // Verify that RAN multiplier from open is used. 2375 CccOpenRangingParams cccOpenRangingParams = (CccOpenRangingParams) uwbSession.getParams(); 2376 assertThat(cccOpenRangingParams.getRanMultiplier()).isEqualTo(4); 2377 } 2378 2379 @Test execStartRanging_executionException()2380 public void execStartRanging_executionException() throws Exception { 2381 UwbSession uwbSession = prepareExistingUwbSession(); 2382 // set up for start ranging 2383 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2384 .when(uwbSession).getSessionState(); 2385 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2386 .thenThrow(new IllegalStateException()); 2387 2388 mUwbSessionManager.startRanging( 2389 uwbSession.getSessionHandle(), uwbSession.getParams()); 2390 mTestLooper.dispatchAll(); 2391 2392 verify(mUwbMetrics).longRangingStartEvent( 2393 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2394 } 2395 2396 @Test execStartRanging_nativeStartRangingFailed()2397 public void execStartRanging_nativeStartRangingFailed() throws Exception { 2398 UwbSession uwbSession = prepareExistingUwbSession(); 2399 // set up for start ranging 2400 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ACTIVE) 2401 .when(uwbSession).getSessionState(); 2402 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2403 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 2404 2405 mUwbSessionManager.startRanging( 2406 uwbSession.getSessionHandle(), uwbSession.getParams()); 2407 mTestLooper.dispatchAll(); 2408 2409 verify(mUwbSessionNotificationManager).onRangingStartFailed( 2410 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2411 verify(mUwbMetrics).longRangingStartEvent( 2412 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2413 } 2414 2415 @Test execStartRanging_wrongSessionState()2416 public void execStartRanging_wrongSessionState() throws Exception { 2417 UwbSession uwbSession = prepareExistingUwbSession(); 2418 // set up for start ranging 2419 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE, UwbUciConstants.UWB_SESSION_STATE_ERROR) 2420 .when(uwbSession).getSessionState(); 2421 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2422 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2423 2424 mUwbSessionManager.startRanging( 2425 uwbSession.getSessionHandle(), uwbSession.getParams()); 2426 mTestLooper.dispatchAll(); 2427 2428 verify(mUwbSessionNotificationManager).onRangingStartFailed( 2429 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2430 verify(mUwbMetrics).longRangingStartEvent( 2431 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2432 } 2433 doTest_sendData_success_validUwbSession(byte[] macAddress, int dataTransferStatus)2434 private void doTest_sendData_success_validUwbSession(byte[] macAddress, int dataTransferStatus) 2435 throws Exception { 2436 UwbAddress uwbAddress = UwbAddress.fromBytes(macAddress); 2437 UwbSession uwbSession = prepareExistingUwbSession(); 2438 2439 // Setup the UwbSession to start ranging (and move it to active state). 2440 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 2441 when(mNativeUwbManager.startRanging(eq(TEST_SESSION_ID), anyString())) 2442 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2443 2444 mUwbSessionManager.startRanging(uwbSession.getSessionHandle(), uwbSession.getParams()); 2445 mTestLooper.dispatchAll(); 2446 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE).when(uwbSession).getSessionState(); 2447 2448 // Send data on the UWB session. 2449 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), eq(macAddress), 2450 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2451 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2452 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2453 2454 mUwbSessionManager.sendData( 2455 uwbSession.getSessionHandle(), uwbAddress, PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2456 mTestLooper.dispatchNext(); 2457 2458 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), eq(macAddress), 2459 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2460 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2461 2462 // A DataTransferStatusNtf is received indicating success. 2463 mUwbSessionManager.onDataSendStatus( 2464 uwbSession.getSessionId(), dataTransferStatus, DATA_SEQUENCE_NUM); 2465 verify(mUwbSessionNotificationManager).onDataSent( 2466 eq(uwbSession), eq(uwbAddress), eq(PERSISTABLE_BUNDLE)); 2467 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2468 } 2469 2470 // Test case for scenario when a Data packet is successfully sent to a remote device (in 2471 // extended MacAddress format). The DataTransferStatus notification returns a success status 2472 // code (STATUS_CODE_DATA_TRANSFER_REPETITION_OK). 2473 @Test sendData_success_validUwbSession_extendedMacAddress_statusRepetitionOk()2474 public void sendData_success_validUwbSession_extendedMacAddress_statusRepetitionOk() 2475 throws Exception { 2476 doTest_sendData_success_validUwbSession( 2477 PEER_EXTENDED_MAC_ADDRESS, STATUS_CODE_DATA_TRANSFER_REPETITION_OK); 2478 } 2479 2480 // Test case for scenario when a Data packet is successfully sent to a remote device (in 2481 // extended MacAddress format). The DataTransferStatus notification returns a success status 2482 // code (STATUS_CODE_OK). 2483 @Test sendData_success_validUwbSession_extendedMacAddress_statusOk()2484 public void sendData_success_validUwbSession_extendedMacAddress_statusOk() 2485 throws Exception { 2486 doTest_sendData_success_validUwbSession(PEER_EXTENDED_MAC_ADDRESS, STATUS_CODE_OK); 2487 } 2488 2489 // Test case for scenario when a Data packet is successfully sent to a remote device (in 2490 // short MacAddress format). The DataTransferStatus notification returns a success status 2491 // code (STATUS_CODE_DATA_TRANSFER_REPETITION_OK). 2492 @Test sendData_success_validUwbSession_shortMacAddress_statusRepetitionOk()2493 public void sendData_success_validUwbSession_shortMacAddress_statusRepetitionOk() 2494 throws Exception { 2495 doTest_sendData_success_validUwbSession( 2496 PEER_EXTENDED_SHORT_MAC_ADDRESS, STATUS_CODE_DATA_TRANSFER_REPETITION_OK); 2497 } 2498 2499 // Test case for scenario when a Data packet is successfully sent to a remote device (in 2500 // short MacAddress format). The DataTransferStatus notification returns a success status 2501 // code (STATUS_CODE_OK). 2502 @Test sendData_success_validUwbSession_shortMacAddress_statusOk()2503 public void sendData_success_validUwbSession_shortMacAddress_statusOk() throws Exception { 2504 doTest_sendData_success_validUwbSession(PEER_EXTENDED_SHORT_MAC_ADDRESS, STATUS_CODE_OK); 2505 } 2506 2507 @Test sendData_success_sequenceNumberRollover()2508 public void sendData_success_sequenceNumberRollover() throws Exception { 2509 // Setup a UwbSession to start ranging (and move it to active state). 2510 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2511 clearInvocations(mNativeUwbManager); 2512 2513 // Send 257 data packets on the UWB session, so that the UCI sequence number rolls over, 2514 // back to 0. 2515 when(mNativeUwbManager.sendData(anyInt(), any(), anyByte(), anyByte(), any(), anyString())) 2516 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2517 2518 for (int i = 0; i <= 256; i++) { 2519 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2520 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2521 mTestLooper.dispatchNext(); 2522 } 2523 2524 // Verify that there are 257 calls to mNativeUwbManager.sendData(), with the important 2525 // thing here being that there should be 2 calls for sequence_number = 0, and 1 call for all 2526 // the other sequence number values [1-255]. 2527 for (int i = 0; i < 256; i++) { 2528 int expectedCount = (i == 0) ? 2 : 1; 2529 verify(mNativeUwbManager, times(expectedCount)).sendData(eq(TEST_SESSION_ID), 2530 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2531 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq((byte) i), 2532 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2533 } 2534 verifyNoMoreInteractions(mNativeUwbManager); 2535 verify(mUwbMetrics, times(257)).logDataTx(eq(uwbSession), 2536 eq(UwbUciConstants.STATUS_CODE_OK)); 2537 } 2538 2539 @Test sendData_missingSessionHandle()2540 public void sendData_missingSessionHandle() throws Exception { 2541 // Setup a UwbSession to start ranging (and move it to active state). 2542 prepareExistingUwbSessionActive(); 2543 2544 // Send a Data packet with null SessionHandle, it should result in an error. 2545 mUwbSessionManager.sendData( 2546 null /* sessionHandle */, PEER_EXTENDED_UWB_ADDRESS, PERSISTABLE_BUNDLE, 2547 DATA_PAYLOAD); 2548 mTestLooper.dispatchNext(); 2549 2550 verify(mNativeUwbManager, never()).sendData( 2551 eq(TEST_SESSION_ID), eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2552 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2553 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2554 verify(mUwbSessionNotificationManager).onDataSendFailed( 2555 eq(null), eq(PEER_EXTENDED_UWB_ADDRESS), 2556 eq(UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST), eq(PERSISTABLE_BUNDLE)); 2557 } 2558 2559 @Test sendData_invalidUwbSessionHandle()2560 public void sendData_invalidUwbSessionHandle() throws Exception { 2561 // Setup a uwbSession UwbSession to start ranging (and move it to active state), and a 2562 // different sessionHandle that doesn't map to the uwbSession. 2563 prepareExistingUwbSessionActive(); 2564 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 2565 2566 // Send a Data packet on the non-active UWB Session. 2567 mUwbSessionManager.sendData( 2568 sessionHandle, PEER_EXTENDED_UWB_ADDRESS, PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2569 mTestLooper.dispatchNext(); 2570 2571 verify(mNativeUwbManager, never()).sendData( 2572 eq(TEST_SESSION_ID), eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2573 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2574 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2575 verify(mUwbSessionNotificationManager).onDataSendFailed( 2576 eq(null), eq(PEER_EXTENDED_UWB_ADDRESS), 2577 eq(UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST), eq(PERSISTABLE_BUNDLE)); 2578 } 2579 2580 @Test sendData_invalidUwbSessionState()2581 public void sendData_invalidUwbSessionState() throws Exception { 2582 // Setup a uwbSession and don't start ranging, so it remains in IDLE state. 2583 UwbSession uwbSession = prepareExistingUwbSession(); 2584 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 2585 2586 // Attempt to send data on the UWB session. 2587 mUwbSessionManager.sendData( 2588 uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, PERSISTABLE_BUNDLE, null); 2589 mTestLooper.dispatchNext(); 2590 2591 verify(mNativeUwbManager, never()).sendData( 2592 eq(TEST_SESSION_ID), eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2593 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2594 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2595 verify(mUwbSessionNotificationManager).onDataSendFailed( 2596 eq(uwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 2597 eq(UwbUciConstants.STATUS_CODE_FAILED), eq(PERSISTABLE_BUNDLE)); 2598 } 2599 2600 @Test sendData_missingDataPayload()2601 public void sendData_missingDataPayload() throws Exception { 2602 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2603 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2604 2605 // Attempt to send data on the UWB session. 2606 mUwbSessionManager.sendData( 2607 uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, PERSISTABLE_BUNDLE, null); 2608 mTestLooper.dispatchNext(); 2609 2610 verify(mNativeUwbManager, never()).sendData( 2611 eq(TEST_SESSION_ID), eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2612 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2613 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2614 verify(mUwbSessionNotificationManager).onDataSendFailed( 2615 eq(uwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 2616 eq(UwbUciConstants.STATUS_CODE_INVALID_PARAM), eq(PERSISTABLE_BUNDLE)); 2617 } 2618 2619 @Test sendData_missingRemoteDevice()2620 public void sendData_missingRemoteDevice() throws Exception { 2621 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2622 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2623 2624 // Attempt to send data on the UWB session. 2625 mUwbSessionManager.sendData( 2626 uwbSession.getSessionHandle(), null, PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2627 mTestLooper.dispatchNext(); 2628 2629 verify(mNativeUwbManager, never()).sendData( 2630 eq(TEST_SESSION_ID), eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2631 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2632 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2633 verify(mUwbSessionNotificationManager).onDataSendFailed( 2634 eq(uwbSession), eq(null), 2635 eq(UwbUciConstants.STATUS_CODE_INVALID_PARAM), eq(PERSISTABLE_BUNDLE)); 2636 } 2637 2638 @Test sendData_dataSendFailure()2639 public void sendData_dataSendFailure() throws Exception { 2640 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2641 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2642 2643 // Attempt to send data on the UWB session. 2644 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), 2645 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2646 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2647 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2648 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 2649 2650 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2651 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2652 mTestLooper.dispatchNext(); 2653 2654 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), 2655 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2656 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2657 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2658 verify(mUwbSessionNotificationManager).onDataSendFailed( 2659 eq(uwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 2660 eq(UwbUciConstants.STATUS_CODE_FAILED), eq(PERSISTABLE_BUNDLE)); 2661 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2662 } 2663 2664 @Test onDataSendStatus_sessionNotFound()2665 public void onDataSendStatus_sessionNotFound() throws Exception { 2666 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2667 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2668 clearInvocations(mUwbSessionNotificationManager); 2669 2670 // Send data on the UWB session. 2671 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), 2672 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2673 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2674 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2675 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2676 2677 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2678 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2679 mTestLooper.dispatchNext(); 2680 2681 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), 2682 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2683 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2684 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2685 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2686 2687 // We receive a DataTransferStatusNtf with a sessionId for a different UwbSession, so it 2688 // should be dropped (no onDataSend()/onDataSendFailure() notifications sent). 2689 mUwbSessionManager.onDataSendStatus(TEST_SESSION_ID_2, STATUS_CODE_OK, DATA_SEQUENCE_NUM); 2690 verifyNoMoreInteractions(mUwbSessionNotificationManager); 2691 } 2692 2693 @Test onDataSendStatus_dataSndPacketNotFound()2694 public void onDataSendStatus_dataSndPacketNotFound() throws Exception { 2695 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2696 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2697 clearInvocations(mUwbSessionNotificationManager); 2698 2699 // Send data on the UWB session. 2700 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), 2701 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2702 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2703 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2704 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2705 2706 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2707 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2708 mTestLooper.dispatchNext(); 2709 2710 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), 2711 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2712 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2713 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2714 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2715 2716 // We receive a DataTransferStatusNtf with an incorrect UCI sequence number (for which a 2717 // packet was never sent), so it should be dropped (no onDataSend()/onDataSendFailure() 2718 // notifications sent). 2719 mUwbSessionManager.onDataSendStatus(TEST_SESSION_ID, STATUS_CODE_OK, DATA_SEQUENCE_NUM_1); 2720 verifyNoMoreInteractions(mUwbSessionNotificationManager); 2721 } 2722 2723 @Test onDataSendStatus_errorStatus()2724 public void onDataSendStatus_errorStatus() throws Exception { 2725 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2726 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2727 clearInvocations(mUwbSessionNotificationManager); 2728 2729 // Send data on the UWB session. 2730 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), 2731 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2732 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2733 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2734 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2735 2736 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2737 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2738 mTestLooper.dispatchNext(); 2739 2740 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), 2741 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2742 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2743 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2744 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2745 2746 // We receive a DataTransferStatusNtf with an error status code. 2747 mUwbSessionManager.onDataSendStatus(TEST_SESSION_ID, 2748 STATUS_CODE_DATA_TRANSFER_ERROR_DATA_TRANSFER, DATA_SEQUENCE_NUM); 2749 verify(mUwbSessionNotificationManager).onDataSendFailed( 2750 eq(uwbSession), eq(PEER_EXTENDED_UWB_ADDRESS), 2751 eq(STATUS_CODE_DATA_TRANSFER_ERROR_DATA_TRANSFER), eq(PERSISTABLE_BUNDLE)); 2752 } 2753 2754 @Test onDataSendStatus_neverReceived()2755 public void onDataSendStatus_neverReceived() throws Exception { 2756 // Setup a uwbSession UwbSession to start ranging (and move it to active state). 2757 UwbSession uwbSession = prepareExistingUwbSessionActive(); 2758 clearInvocations(mUwbSessionNotificationManager); 2759 2760 // Send data on the UWB session. 2761 when(mNativeUwbManager.sendData(eq(TEST_SESSION_ID), 2762 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2763 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2764 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID))) 2765 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2766 2767 mUwbSessionManager.sendData(uwbSession.getSessionHandle(), PEER_EXTENDED_UWB_ADDRESS, 2768 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 2769 mTestLooper.dispatchNext(); 2770 2771 verify(mNativeUwbManager).sendData(eq(TEST_SESSION_ID), 2772 eq(PEER_EXTENDED_UWB_ADDRESS.toBytes()), 2773 eq(UwbUciConstants.UWB_DESTINATION_END_POINT_HOST), eq(DATA_SEQUENCE_NUM), 2774 eq(DATA_PAYLOAD), eq(TEST_CHIP_ID)); 2775 verify(mUwbMetrics).logDataTx(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 2776 2777 // We never receive a DataTransferStatusNtf, so no onDataSend()/onDataSendFailure() 2778 // notifications are sent. 2779 verifyNoMoreInteractions(mUwbSessionNotificationManager); 2780 assertNotNull(uwbSession.getSendDataInfo(DATA_SEQUENCE_NUM)); 2781 2782 // Eventually Session DeInit is called, and the stored SendDataInfo(s) should be deleted. 2783 mUwbSessionManager.deInitSession(uwbSession.getSessionHandle()); 2784 mTestLooper.dispatchNext(); 2785 assertNull(uwbSession.getSendDataInfo(DATA_SEQUENCE_NUM)); 2786 } 2787 2788 @Test stopRanging_sessionStateActive()2789 public void stopRanging_sessionStateActive() throws Exception { 2790 UwbSession uwbSession = prepareExistingUwbSession(); 2791 // set up for stop ranging 2792 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE).when(uwbSession).getSessionState(); 2793 2794 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2795 2796 assertThat(mTestLooper.nextMessage().what).isEqualTo(3); // SESSION_STOP_RANGING 2797 } 2798 2799 @Test stopRanging_sessionStateIdle()2800 public void stopRanging_sessionStateIdle() throws Exception { 2801 UwbSession uwbSession = prepareExistingUwbSession(); 2802 // set up for stop ranging 2803 doReturn(UwbUciConstants.UWB_SESSION_STATE_IDLE).when(uwbSession).getSessionState(); 2804 2805 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2806 2807 verify(mUwbSessionNotificationManager).onRangingStopped( 2808 eq(uwbSession), 2809 eq(UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS)); 2810 verify(mUwbMetrics).longRangingStopEvent(eq(uwbSession)); 2811 } 2812 2813 @Test stopRanging_sessionStateError()2814 public void stopRanging_sessionStateError() throws Exception { 2815 UwbSession uwbSession = prepareExistingUwbSession(); 2816 // set up for stop ranging 2817 doReturn(UwbUciConstants.UWB_SESSION_STATE_ERROR).when(uwbSession).getSessionState(); 2818 2819 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2820 2821 verify(mUwbSessionNotificationManager).onRangingStopFailed( 2822 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_REJECTED)); 2823 } 2824 2825 @Test execStopRanging_success()2826 public void execStopRanging_success() throws Exception { 2827 UwbSession uwbSession = prepareExistingUwbSession(); 2828 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, UwbUciConstants.UWB_SESSION_STATE_IDLE) 2829 .when(uwbSession).getSessionState(); 2830 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 2831 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2832 2833 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2834 mTestLooper.dispatchNext(); 2835 2836 verify(mUwbInjector).runTaskOnSingleThreadExecutor( 2837 any(), eq(IUwbAdapter.RANGING_SESSION_START_THRESHOLD_MS)); 2838 verify(mUwbSessionNotificationManager) 2839 .onRangingStoppedWithApiReasonCode(eq(uwbSession), 2840 eq(RangingChangeReason.LOCAL_API)); 2841 verify(mUwbMetrics).longRangingStopEvent(eq(uwbSession)); 2842 } 2843 2844 @Test execStopRanging_exception()2845 public void execStopRanging_exception() throws Exception { 2846 UwbSession uwbSession = prepareExistingUwbSession(); 2847 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, UwbUciConstants.UWB_SESSION_STATE_IDLE) 2848 .when(uwbSession).getSessionState(); 2849 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 2850 .thenThrow(new IllegalStateException()); 2851 2852 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2853 mTestLooper.dispatchNext(); 2854 2855 verify(mUwbSessionNotificationManager, never()).onRangingStopped(any(), anyInt()); 2856 } 2857 2858 @Test execStopRanging_nativeFailed()2859 public void execStopRanging_nativeFailed() throws Exception { 2860 UwbSession uwbSession = prepareExistingUwbSession(); 2861 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, UwbUciConstants.UWB_SESSION_STATE_IDLE) 2862 .when(uwbSession).getSessionState(); 2863 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 2864 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 2865 2866 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 2867 mTestLooper.dispatchNext(); 2868 2869 verify(mUwbSessionNotificationManager) 2870 .onRangingStopFailed(eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 2871 verify(mUwbMetrics, never()).longRangingStopEvent(eq(uwbSession)); 2872 } 2873 2874 @Test reconfigure_notExistingSession()2875 public void reconfigure_notExistingSession() { 2876 int status = mUwbSessionManager.reconfigure(mock(SessionHandle.class), mock(Params.class)); 2877 2878 assertThat(status).isEqualTo(UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST); 2879 } 2880 buildReconfigureParams()2881 private FiraRangingReconfigureParams buildReconfigureParams() { 2882 return buildReconfigureParams(FiraParams.MULTICAST_LIST_UPDATE_ACTION_ADD); 2883 } 2884 buildReconfigureParams(int action)2885 private FiraRangingReconfigureParams buildReconfigureParams(int action) { 2886 FiraRangingReconfigureParams reconfigureParams = 2887 new FiraRangingReconfigureParams.Builder() 2888 .setAddressList(new UwbAddress[] { 2889 UwbAddress.fromBytes(new byte[] { (byte) 0x01, (byte) 0x02 }) }) 2890 .setAction(action) 2891 .setSubSessionIdList(new int[] { 2 }) 2892 .build(); 2893 2894 return spy(reconfigureParams); 2895 } 2896 buildReconfigureParamsV2()2897 private FiraRangingReconfigureParams buildReconfigureParamsV2() { 2898 return buildReconfigureParamsV2( 2899 FiraParams.P_STS_MULTICAST_LIST_UPDATE_ACTION_ADD_16_BYTE); 2900 } 2901 buildReconfigureParamsV2(int action)2902 private FiraRangingReconfigureParams buildReconfigureParamsV2(int action) { 2903 FiraRangingReconfigureParams reconfigureParams = 2904 new FiraRangingReconfigureParams.Builder() 2905 .setAddressList(new UwbAddress[] { 2906 UwbAddress.fromBytes(new byte[] { (byte) 0x01, (byte) 0x02 }) }) 2907 .setAction(action) 2908 .setSubSessionIdList(new int[] { 2 }) 2909 .setSubSessionKeyList(new byte[] {0, 0, 0, 0, 1, 1, 1, 1, 2910 2, 2, 2, 2, 3, 3, 3, 3}) 2911 .build(); 2912 2913 return spy(reconfigureParams); 2914 } 2915 2916 @Test reconfigure_existingSession()2917 public void reconfigure_existingSession() throws Exception { 2918 UwbSession uwbSession = prepareExistingUwbSession(); 2919 2920 int status = mUwbSessionManager.reconfigure( 2921 uwbSession.getSessionHandle(), buildReconfigureParamsV2()); 2922 2923 assertThat(status).isEqualTo(0); 2924 assertThat(mTestLooper.nextMessage().what).isEqualTo(4); // SESSION_RECONFIGURE_RANGING 2925 } 2926 2927 @Test execReconfigureAddControlee_success()2928 public void execReconfigureAddControlee_success() throws Exception { 2929 UwbSession uwbSession = prepareExistingUwbSession(); 2930 FiraRangingReconfigureParams reconfigureParams = 2931 buildReconfigureParams(); 2932 when(mNativeUwbManager 2933 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 2934 any(), anyString())) 2935 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2936 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 2937 mock(UwbMulticastListUpdateStatus.class); 2938 when(uwbMulticastListUpdateStatus.getNumOfControlee()).thenReturn(1); 2939 when(uwbMulticastListUpdateStatus.getControleeUwbAddresses()) 2940 .thenReturn(new UwbAddress[] {UWB_DEST_ADDRESS_2}); 2941 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 2942 new int[] { UwbUciConstants.STATUS_CODE_OK }); 2943 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 2944 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 2945 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 2946 2947 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 2948 mTestLooper.dispatchNext(); 2949 2950 // Make sure the original address is still there. 2951 assertThat(uwbSession.getControleeList().stream() 2952 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS))) 2953 .isTrue(); 2954 2955 // Make sure this new address was added. 2956 assertThat(uwbSession.getControleeList().stream() 2957 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS_2))) 2958 .isTrue(); 2959 2960 byte[] dstAddress = 2961 getComputedMacAddress(reconfigureParams.getAddressList()[0].toBytes()); 2962 verify(mNativeUwbManager).controllerMulticastListUpdate( 2963 uwbSession.getSessionId(), reconfigureParams.getAction(), 1, 2964 dstAddress, reconfigureParams.getSubSessionIdList(), null, 2965 uwbSession.getChipId()); 2966 verify(mUwbSessionNotificationManager).onControleeAdded(eq(uwbSession)); 2967 verify(mUwbSessionNotificationManager).onRangingReconfigured(eq(uwbSession)); 2968 } 2969 2970 @Test execReconfigureRemoveControleeV1_success()2971 public void execReconfigureRemoveControleeV1_success() throws Exception { 2972 UwbSession uwbSession = prepareExistingUwbSession(); 2973 FiraRangingReconfigureParams reconfigureParams = 2974 buildReconfigureParams(FiraParams.MULTICAST_LIST_UPDATE_ACTION_DELETE); 2975 when(mNativeUwbManager 2976 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 2977 any(), anyString())) 2978 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 2979 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 2980 mock(UwbMulticastListUpdateStatus.class); 2981 when(uwbMulticastListUpdateStatus.getNumOfControlee()).thenReturn(1); 2982 when(uwbMulticastListUpdateStatus.getControleeUwbAddresses()) 2983 .thenReturn(new UwbAddress[] {UWB_DEST_ADDRESS}); 2984 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 2985 new int[] { UwbUciConstants.STATUS_CODE_OK }); 2986 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 2987 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 2988 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 2989 2990 // Make sure the address exists in the first place. This should have been set up by 2991 // prepareExistingUwbSession 2992 assertThat(uwbSession.getControleeList().stream() 2993 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS))) 2994 .isTrue(); 2995 2996 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 2997 mTestLooper.dispatchNext(); 2998 2999 // Make sure the address was removed. 3000 assertThat(uwbSession.getControleeList().stream() 3001 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS))) 3002 .isFalse(); 3003 3004 byte[] dstAddress = getComputedMacAddress(reconfigureParams.getAddressList()[0].toBytes()); 3005 verify(mNativeUwbManager).controllerMulticastListUpdate( 3006 uwbSession.getSessionId(), reconfigureParams.getAction(), 1, 3007 dstAddress, reconfigureParams.getSubSessionIdList(), null, 3008 uwbSession.getChipId()); 3009 verify(mUwbSessionNotificationManager).onControleeRemoved(eq(uwbSession)); 3010 verify(mUwbSessionNotificationManager).onRangingReconfigured(eq(uwbSession)); 3011 } 3012 3013 @Test execReconfigureAddControleeV2_success()3014 public void execReconfigureAddControleeV2_success() throws Exception { 3015 UwbSession uwbSession = prepareExistingUwbSession(); 3016 FiraRangingReconfigureParams reconfigureParams = 3017 buildReconfigureParamsV2(); 3018 when(mNativeUwbManager 3019 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 3020 any(), anyString())) 3021 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3022 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 3023 mock(UwbMulticastListUpdateStatus.class); 3024 when(uwbMulticastListUpdateStatus.getNumOfControlee()).thenReturn(1); 3025 when(uwbMulticastListUpdateStatus.getControleeUwbAddresses()) 3026 .thenReturn(new UwbAddress[] {UWB_DEST_ADDRESS_2}); 3027 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 3028 new int[] { UwbUciConstants.STATUS_CODE_OK }); 3029 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 3030 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 3031 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 3032 3033 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3034 mTestLooper.dispatchNext(); 3035 3036 // Make sure the original address is still there. 3037 assertThat(uwbSession.getControleeList().stream() 3038 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS))) 3039 .isTrue(); 3040 3041 // Make sure this new address was added. 3042 assertThat(uwbSession.getControleeList().stream() 3043 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS_2))) 3044 .isTrue(); 3045 3046 byte[] dstAddress = getComputedMacAddress(reconfigureParams.getAddressList()[0].toBytes()); 3047 verify(mNativeUwbManager).controllerMulticastListUpdate( 3048 uwbSession.getSessionId(), reconfigureParams.getAction(), 1, 3049 dstAddress, reconfigureParams.getSubSessionIdList(), 3050 reconfigureParams.getSubSessionKeyList(), uwbSession.getChipId()); 3051 verify(mUwbSessionNotificationManager).onControleeAdded(eq(uwbSession)); 3052 verify(mUwbSessionNotificationManager).onRangingReconfigured(eq(uwbSession)); 3053 } 3054 3055 @Test execReconfigure_nativeUpdateFailed()3056 public void execReconfigure_nativeUpdateFailed() throws Exception { 3057 UwbSession uwbSession = prepareExistingUwbSession(); 3058 FiraRangingReconfigureParams reconfigureParams = 3059 buildReconfigureParamsV2(); 3060 when(mNativeUwbManager 3061 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 3062 any(), anyString())) 3063 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 3064 3065 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3066 mTestLooper.dispatchNext(); 3067 3068 verify(mUwbSessionNotificationManager).onControleeAddFailed(eq(uwbSession), 3069 eq(UwbUciConstants.STATUS_CODE_FAILED)); 3070 verify(mUwbSessionNotificationManager).onRangingReconfigureFailed( 3071 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3072 } 3073 3074 @Test execReconfigure_uwbSessionUpdateMixedSuccess()3075 public void execReconfigure_uwbSessionUpdateMixedSuccess() throws Exception { 3076 UwbSession uwbSession = prepareExistingUwbSession(); 3077 FiraRangingReconfigureParams reconfigureParams = 3078 buildReconfigureParamsV2(); 3079 when(mNativeUwbManager 3080 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 3081 any(), anyString())) 3082 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3083 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 3084 mock(UwbMulticastListUpdateStatus.class); 3085 when(uwbMulticastListUpdateStatus.getNumOfControlee()).thenReturn(2); 3086 when(uwbMulticastListUpdateStatus.getControleeUwbAddresses()).thenReturn( 3087 new UwbAddress[] { UWB_DEST_ADDRESS_2, UWB_DEST_ADDRESS_3 }); 3088 // One fail, one success 3089 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 3090 new int[] { UwbUciConstants.STATUS_CODE_FAILED, UwbUciConstants.STATUS_CODE_OK }); 3091 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 3092 3093 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3094 mTestLooper.dispatchNext(); 3095 3096 // Fail callback for the first one. 3097 verify(mUwbSessionNotificationManager).onControleeAddFailed(eq(uwbSession), 3098 eq(UwbUciConstants.STATUS_CODE_FAILED)); 3099 // Success callback for the second. 3100 verify(mUwbSessionNotificationManager).onControleeAdded(eq(uwbSession)); 3101 3102 // Make sure the failed address was not added. 3103 assertThat(uwbSession.getControleeList().stream() 3104 .anyMatch(e -> e.getUwbAddress().equals(UWB_DEST_ADDRESS_2))) 3105 .isFalse(); 3106 3107 // Overall reconfigure fail. 3108 verify(mUwbSessionNotificationManager).onRangingReconfigureFailed( 3109 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3110 } 3111 3112 @Test execReconfigure_uwbSessionUpdateFailed()3113 public void execReconfigure_uwbSessionUpdateFailed() throws Exception { 3114 UwbSession uwbSession = prepareExistingUwbSession(); 3115 FiraRangingReconfigureParams reconfigureParams = 3116 buildReconfigureParamsV2(); 3117 when(mNativeUwbManager 3118 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 3119 any(), anyString())) 3120 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3121 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 3122 mock(UwbMulticastListUpdateStatus.class); 3123 when(uwbMulticastListUpdateStatus.getNumOfControlee()).thenReturn(1); 3124 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 3125 new int[] { UwbUciConstants.STATUS_CODE_FAILED }); 3126 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 3127 3128 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3129 mTestLooper.dispatchNext(); 3130 3131 verify(mUwbSessionNotificationManager).onControleeAddFailed(eq(uwbSession), 3132 eq(UwbUciConstants.STATUS_CODE_FAILED)); 3133 verify(mUwbSessionNotificationManager).onRangingReconfigureFailed( 3134 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3135 } 3136 3137 @Test execReconfigureBlockStriding_success_stop()3138 public void execReconfigureBlockStriding_success_stop() throws Exception { 3139 UwbSession uwbSession = prepareExistingUwbSession(); 3140 FiraRangingReconfigureParams reconfigureParams = 3141 new FiraRangingReconfigureParams.Builder() 3142 .setBlockStrideLength(10) 3143 .build(); 3144 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 3145 .thenReturn(UwbUciConstants.STATUS_CODE_OK); 3146 3147 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3148 mTestLooper.dispatchNext(); 3149 3150 verify(mUwbSessionNotificationManager).onRangingReconfigured(uwbSession); 3151 3152 doReturn(UwbUciConstants.UWB_SESSION_STATE_ACTIVE, UwbUciConstants.UWB_SESSION_STATE_IDLE) 3153 .when(uwbSession).getSessionState(); 3154 when(mNativeUwbManager.stopRanging(eq(TEST_SESSION_ID), anyString())) 3155 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3156 3157 mUwbSessionManager.stopRanging(uwbSession.getSessionHandle()); 3158 mTestLooper.dispatchNext(); 3159 3160 verify(mUwbInjector).runTaskOnSingleThreadExecutor( 3161 any(), eq(TEST_RANGING_INTERVAL_MS * 4 * 11)); 3162 verify(mUwbSessionNotificationManager) 3163 .onRangingStoppedWithApiReasonCode(eq(uwbSession), 3164 eq(RangingChangeReason.LOCAL_API)); 3165 verify(mUwbMetrics).longRangingStopEvent(eq(uwbSession)); 3166 } 3167 3168 @Test execReconfigure_setAppConfigurationsFailed()3169 public void execReconfigure_setAppConfigurationsFailed() throws Exception { 3170 UwbSession uwbSession = prepareExistingUwbSession(); 3171 FiraRangingReconfigureParams reconfigureParams = 3172 buildReconfigureParamsV2(); 3173 when(mNativeUwbManager 3174 .controllerMulticastListUpdate(anyInt(), anyInt(), anyInt(), any(), any(), 3175 any(), anyString())) 3176 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 3177 UwbMulticastListUpdateStatus uwbMulticastListUpdateStatus = 3178 mock(UwbMulticastListUpdateStatus.class); 3179 when(uwbMulticastListUpdateStatus.getStatus()).thenReturn( 3180 new int[] { UwbUciConstants.STATUS_CODE_OK }); 3181 doReturn(uwbMulticastListUpdateStatus).when(uwbSession).getMulticastListUpdateStatus(); 3182 when(mUwbConfigurationManager.setAppConfigurations(anyInt(), any(), anyString())) 3183 .thenReturn(UwbUciConstants.STATUS_CODE_FAILED); 3184 3185 mUwbSessionManager.reconfigure(uwbSession.getSessionHandle(), reconfigureParams); 3186 mTestLooper.dispatchNext(); 3187 3188 verify(mUwbSessionNotificationManager).onRangingReconfigureFailed( 3189 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3190 } 3191 3192 @Test testQueryDataSize()3193 public void testQueryDataSize() throws Exception { 3194 UwbSession uwbSession = prepareExistingUwbSession(); 3195 3196 when(mNativeUwbManager.queryMaxDataSizeBytes( 3197 eq(uwbSession.getSessionId()), eq(TEST_CHIP_ID))) 3198 .thenReturn(MAX_DATA_SIZE); 3199 assertThat(mUwbSessionManager.queryMaxDataSizeBytes(uwbSession.getSessionHandle())) 3200 .isEqualTo(MAX_DATA_SIZE); 3201 } 3202 3203 @Test testQueryDataSize_whenUwbSessionDoesNotExist()3204 public void testQueryDataSize_whenUwbSessionDoesNotExist() throws Exception { 3205 SessionHandle mockSessionHandle = mock(SessionHandle.class); 3206 assertThrows(IllegalStateException.class, 3207 () -> mUwbSessionManager.queryMaxDataSizeBytes(mockSessionHandle)); 3208 } 3209 3210 @Test deInitSession_notExistedSession()3211 public void deInitSession_notExistedSession() { 3212 doReturn(false).when(mUwbSessionManager).isExistedSession(any()); 3213 3214 mUwbSessionManager.deInitSession(mock(SessionHandle.class)); 3215 3216 verify(mUwbSessionManager, never()).getSessionId(any()); 3217 assertThat(mTestLooper.nextMessage()).isNull(); 3218 } 3219 3220 @Test deInitSession_success()3221 public void deInitSession_success() { 3222 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 3223 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 3224 3225 mUwbSessionManager.deInitSession(mock(SessionHandle.class)); 3226 3227 verify(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 3228 assertThat(mTestLooper.nextMessage().what).isEqualTo(5); // SESSION_DEINIT 3229 3230 verifyZeroInteractions(mUwbAdvertiseManager); 3231 } 3232 3233 @Test deInitSession_success_afterOwrAoaMeasurement()3234 public void deInitSession_success_afterOwrAoaMeasurement() { 3235 UwbSession mockUwbSession = mock(UwbSession.class); 3236 when(mockUwbSession.getWaitObj()).thenReturn(mock(WaitObj.class)); 3237 when(mockUwbSession.getSessionHandle()).thenReturn(mock(SessionHandle.class)); 3238 doReturn(mockUwbSession).when(mUwbSessionManager).getUwbSession(eq(TEST_SESSION_ID)); 3239 3240 // Setup the UwbSession to have the peer device's MacAddress stored (which happens when 3241 // a valid RANGE_DATA_NTF with an OWR AoA Measurement is received). 3242 doReturn(Set.of(PEER_EXTENDED_MAC_ADDRESS_LONG)).when(mockUwbSession) 3243 .getRemoteMacAddressList(); 3244 3245 // Call deInitSession(). 3246 IBinder mockBinder = mock(IBinder.class); 3247 doReturn(mockBinder).when(mockUwbSession).getBinder(); 3248 doReturn(FiraParams.PROTOCOL_NAME).when(mockUwbSession).getProtocolName(); 3249 doReturn(null).when(mockUwbSession).getAnyNonPrivilegedAppInAttributionSource(); 3250 doReturn(true).when(mUwbSessionManager).isExistedSession(any()); 3251 doReturn(TEST_SESSION_ID).when(mUwbSessionManager).getSessionId(any()); 3252 mUwbSessionManager.deInitSession(mock(SessionHandle.class)); 3253 3254 mTestLooper.dispatchNext(); 3255 3256 verify(mUwbAdvertiseManager).removeAdvertiseTarget(PEER_EXTENDED_MAC_ADDRESS_LONG); 3257 } 3258 3259 @Test execDeInitSession()3260 public void execDeInitSession() throws Exception { 3261 UwbSession uwbSession = prepareExistingUwbSession(); 3262 3263 mUwbSessionManager.deInitSession(uwbSession.getSessionHandle()); 3264 3265 assertThat(mTestLooper.nextMessage().what).isEqualTo(5); // SESSION_DEINIT 3266 } 3267 3268 @Test execDeInitSession_success()3269 public void execDeInitSession_success() throws Exception { 3270 UwbSession uwbSession = prepareExistingUwbSession(); 3271 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3272 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3273 3274 mUwbSessionManager.deInitSession(uwbSession.getSessionHandle()); 3275 mTestLooper.dispatchNext(); 3276 3277 verify(mUwbSessionNotificationManager).onRangingClosed( 3278 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 3279 verify(mUwbMetrics).logRangingCloseEvent( 3280 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 3281 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3282 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3283 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3284 verifyZeroInteractions(mUwbAdvertiseManager); 3285 } 3286 3287 @Test execDeInitSession_failed()3288 public void execDeInitSession_failed() throws Exception { 3289 UwbSession uwbSession = prepareExistingUwbSession(); 3290 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3291 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 3292 3293 mUwbSessionManager.deInitSession(uwbSession.getSessionHandle()); 3294 mTestLooper.dispatchNext(); 3295 3296 verify(mUwbSessionNotificationManager).onRangingClosed( 3297 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3298 verify(mUwbAdvertiseManager, never()).removeAdvertiseTarget(isA(Long.class)); 3299 verify(mUwbMetrics).logRangingCloseEvent( 3300 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3301 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3302 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3303 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3304 verifyZeroInteractions(mUwbAdvertiseManager); 3305 } 3306 3307 @Test deinitAllSession()3308 public void deinitAllSession() { 3309 UwbSession mockUwbSession1 = mock(UwbSession.class); 3310 SessionHandle mockSessionHandle1 = mock(SessionHandle.class); 3311 when(mockUwbSession1.getSessionId()).thenReturn(TEST_SESSION_ID); 3312 when(mockUwbSession1.getBinder()).thenReturn(mock(IBinder.class)); 3313 when(mockUwbSession1.getSessionId()).thenReturn(TEST_SESSION_ID); 3314 when(mockUwbSession1.getProtocolName()).thenReturn(FiraParams.PROTOCOL_NAME); 3315 when(mockUwbSession1.getSessionHandle()).thenReturn(mockSessionHandle1); 3316 mUwbSessionManager.mSessionTable.put(mockSessionHandle1, mockUwbSession1); 3317 3318 UwbSession mockUwbSession2 = mock(UwbSession.class); 3319 SessionHandle mockSessionHandle2 = mock(SessionHandle.class); 3320 when(mockUwbSession2.getBinder()).thenReturn(mock(IBinder.class)); 3321 when(mockUwbSession2.getSessionId()).thenReturn(TEST_SESSION_ID + 100); 3322 when(mockUwbSession2.getProtocolName()).thenReturn(FiraParams.PROTOCOL_NAME); 3323 when(mockUwbSession2.getSessionHandle()).thenReturn(mockSessionHandle2); 3324 mUwbSessionManager.mSessionTable.put(mockSessionHandle2, mockUwbSession2); 3325 3326 mUwbSessionManager.deinitAllSession(); 3327 3328 verify(mUwbSessionNotificationManager, times(2)) 3329 .onRangingClosedWithApiReasonCode(any(), eq(RangingChangeReason.SYSTEM_POLICY)); 3330 verify(mUwbSessionManager, times(2)).removeSession(any()); 3331 // TODO: enable it when the deviceReset is enabled. 3332 // verify(mNativeUwbManager).deviceReset(eq(UwbUciConstants.UWBS_RESET)); 3333 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3334 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3335 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3336 } 3337 3338 @Test onSessionStatusNotification_session_deinit()3339 public void onSessionStatusNotification_session_deinit() throws Exception { 3340 UwbSession uwbSession = prepareExistingUwbSession(); 3341 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3342 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3343 3344 mUwbSessionManager.onSessionStatusNotificationReceived( 3345 uwbSession.getSessionId(), UwbUciConstants.UWB_SESSION_STATE_DEINIT, 3346 UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS); 3347 mTestLooper.dispatchNext(); 3348 3349 verify(mUwbSessionNotificationManager).onRangingClosedWithApiReasonCode( 3350 eq(uwbSession), eq(RangingChangeReason.SYSTEM_POLICY)); 3351 verify(mUwbMetrics).logRangingCloseEvent( 3352 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 3353 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3354 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3355 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3356 } 3357 3358 @Test onSessionStatusNotification_session_deinit_after_close()3359 public void onSessionStatusNotification_session_deinit_after_close() throws Exception { 3360 UwbSession uwbSession = prepareExistingUwbSession(); 3361 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3362 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3363 3364 mUwbSessionManager.deinitAllSession(); 3365 verify(mUwbSessionNotificationManager).onRangingClosedWithApiReasonCode( 3366 eq(uwbSession), eq(RangingChangeReason.SYSTEM_POLICY)); 3367 verify(mUwbMetrics).logRangingCloseEvent( 3368 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 3369 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3370 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3371 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3372 3373 // Ignore the stale deinit 3374 mUwbSessionManager.handleOnDeInit(uwbSession); 3375 verifyNoMoreInteractions(mUwbSessionNotificationManager); 3376 } 3377 3378 @Test onSessionStatusNotification_session_deinit_owrAoa()3379 public void onSessionStatusNotification_session_deinit_owrAoa() throws Exception { 3380 Params firaParams = setupFiraParams( 3381 RANGING_DEVICE_ROLE_OBSERVER, Optional.of(ROUND_USAGE_OWR_AOA_MEASUREMENT)); 3382 UwbSession uwbSession = prepareExistingUwbSession(firaParams); 3383 3384 UwbRangingData uwbRangingData = UwbTestUtils.generateRangingData( 3385 RANGING_MEASUREMENT_TYPE_OWR_AOA, MAC_ADDRESSING_MODE_EXTENDED, 3386 UwbUciConstants.STATUS_CODE_OK); 3387 3388 // First call onDataReceived() to get the application payload data. 3389 when(mDeviceConfigFacade.getRxDataMaxPacketsToStore()) 3390 .thenReturn(MAX_RX_DATA_PACKETS_TO_STORE); 3391 mUwbSessionManager.onDataReceived(TEST_SESSION_ID, UwbUciConstants.STATUS_CODE_OK, 3392 DATA_SEQUENCE_NUM, PEER_EXTENDED_MAC_ADDRESS, SOURCE_END_POINT, DEST_END_POINT, 3393 DATA_PAYLOAD); 3394 3395 // Next call onRangeDataNotificationReceived() to process the RANGE_DATA_NTF. Setup 3396 // isPointedTarget() to return "false", as in that scenario the stored AdvertiseTarget 3397 // is not removed. 3398 when(mUwbAdvertiseManager.isPointedTarget(PEER_EXTENDED_MAC_ADDRESS)).thenReturn(false); 3399 mUwbSessionManager.onRangeDataNotificationReceived(uwbRangingData); 3400 3401 verify(mUwbAdvertiseManager).updateAdvertiseTarget(uwbRangingData.mRangingOwrAoaMeasure); 3402 verify(mUwbAdvertiseManager).isPointedTarget(PEER_EXTENDED_MAC_ADDRESS); 3403 3404 // Now call onSessionStatusNotificationReceived() on the same UwbSession, and verify that 3405 // removeAdvertiseTarget() is called to remove any stored OwR AoA Measurement(s). 3406 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3407 .thenReturn((byte) UwbUciConstants.STATUS_CODE_OK); 3408 3409 mUwbSessionManager.onSessionStatusNotificationReceived( 3410 uwbSession.getSessionId(), UwbUciConstants.UWB_SESSION_STATE_DEINIT, 3411 UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS); 3412 mTestLooper.dispatchNext(); 3413 3414 verify(mUwbSessionNotificationManager).onRangingClosedWithApiReasonCode( 3415 eq(uwbSession), eq(RangingChangeReason.SYSTEM_POLICY)); 3416 verify(mUwbMetrics).logRangingCloseEvent( 3417 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_OK)); 3418 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3419 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3420 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3421 3422 verify(mUwbAdvertiseManager).removeAdvertiseTarget(isA(Long.class)); 3423 } 3424 3425 @Test testHandleClientDeath()3426 public void testHandleClientDeath() throws Exception { 3427 UwbSession uwbSession = prepareExistingUwbSession(); 3428 when(mNativeUwbManager.deInitSession(eq(TEST_SESSION_ID), anyString())) 3429 .thenReturn((byte) UwbUciConstants.STATUS_CODE_FAILED); 3430 3431 uwbSession.binderDied(); 3432 3433 verify(mUwbMetrics).logRangingCloseEvent( 3434 eq(uwbSession), eq(UwbUciConstants.STATUS_CODE_FAILED)); 3435 assertThat(mUwbSessionManager.getSessionCount()).isEqualTo(0); 3436 assertThat(mUwbSessionManager.getCccSessionCount()).isEqualTo(0L); 3437 assertThat(mUwbSessionManager.getFiraSessionCount()).isEqualTo(0L); 3438 } 3439 3440 @Test testDtTagRangingRoundsUpdate()3441 public void testDtTagRangingRoundsUpdate() throws Exception { 3442 UwbSession uwbSession = prepareExistingUwbSession(); 3443 byte[] indices = {1, 2}; 3444 DtTagUpdateRangingRoundsStatus status = new DtTagUpdateRangingRoundsStatus(0, 3445 indices.length, indices); 3446 PersistableBundle bundle = new DlTDoARangingRoundsUpdate.Builder() 3447 .setSessionId(uwbSession.getSessionId()) 3448 .setNoOfRangingRounds(indices.length) 3449 .setRangingRoundIndexes(indices) 3450 .build() 3451 .toBundle(); 3452 3453 when(mNativeUwbManager.sessionUpdateDtTagRangingRounds(anyInt(), anyInt(), any(), 3454 anyString())).thenReturn(status); 3455 3456 mUwbSessionManager.rangingRoundsUpdateDtTag(uwbSession.getSessionHandle(), bundle); 3457 mTestLooper.dispatchAll(); 3458 3459 verify(mNativeUwbManager).sessionUpdateDtTagRangingRounds(uwbSession.getSessionId(), 3460 indices.length, indices, uwbSession.getChipId()); 3461 verify(mUwbSessionNotificationManager).onRangingRoundsUpdateStatus(any(), any()); 3462 } 3463 buildReceivedDataInfo(long macAddress)3464 private UwbSessionManager.ReceivedDataInfo buildReceivedDataInfo(long macAddress) { 3465 return buildReceivedDataInfo(macAddress, DATA_SEQUENCE_NUM); 3466 } 3467 buildReceivedDataInfo( long macAddress, long sequenceNum)3468 private UwbSessionManager.ReceivedDataInfo buildReceivedDataInfo( 3469 long macAddress, long sequenceNum) { 3470 UwbSessionManager.ReceivedDataInfo info = new UwbSessionManager.ReceivedDataInfo(); 3471 info.sessionId = TEST_SESSION_ID; 3472 info.status = STATUS_CODE_OK; 3473 info.sequenceNum = sequenceNum; 3474 info.address = macAddress; 3475 info.sourceEndPoint = SOURCE_END_POINT; 3476 info.destEndPoint = DEST_END_POINT; 3477 info.payload = DATA_PAYLOAD; 3478 return info; 3479 } 3480 getComputedMacAddress(byte[] address)3481 private static byte[] getComputedMacAddress(byte[] address) { 3482 if (!SdkLevel.isAtLeastU()) { 3483 return TlvUtil.getReverseBytes(address); 3484 } 3485 return address; 3486 } 3487 } 3488