1 /* 2 * Copyright (C) 2021 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 com.android.server.uwb.UwbTestUtils.DATA_PAYLOAD; 20 import static com.android.server.uwb.UwbTestUtils.PEER_EXTENDED_UWB_ADDRESS; 21 import static com.android.server.uwb.UwbTestUtils.PEER_SHORT_MAC_ADDRESS; 22 import static com.android.server.uwb.UwbTestUtils.PERSISTABLE_BUNDLE; 23 import static com.android.server.uwb.data.UwbUciConstants.MAC_ADDRESSING_MODE_SHORT; 24 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_DL_TDOA; 25 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_OWR_AOA; 26 import static com.android.server.uwb.data.UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY; 27 import static com.android.server.uwb.data.UwbUciConstants.STATUS_CODE_FAILED; 28 29 import static com.google.common.truth.Truth.assertThat; 30 import static com.google.uwb.support.radar.RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES; 31 32 import static org.mockito.ArgumentMatchers.anyInt; 33 import static org.mockito.ArgumentMatchers.argThat; 34 import static org.mockito.ArgumentMatchers.eq; 35 import static org.mockito.ArgumentMatchers.isA; 36 import static org.mockito.Mockito.any; 37 import static org.mockito.Mockito.clearInvocations; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.validateMockitoUsage; 40 import static org.mockito.Mockito.verify; 41 import static org.mockito.Mockito.verifyZeroInteractions; 42 import static org.mockito.Mockito.when; 43 44 import android.content.AttributionSource; 45 import android.os.PersistableBundle; 46 import android.os.RemoteException; 47 import android.platform.test.annotations.Presubmit; 48 import android.platform.test.annotations.RequiresFlagsEnabled; 49 import android.platform.test.flag.junit.CheckFlagsRule; 50 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 51 import android.util.Pair; 52 import android.uwb.IUwbOemExtensionCallback; 53 import android.uwb.IUwbRangingCallbacks; 54 import android.uwb.RangingChangeReason; 55 import android.uwb.RangingReport; 56 import android.uwb.SessionHandle; 57 import android.uwb.UwbAddress; 58 59 import androidx.test.filters.SmallTest; 60 import androidx.test.runner.AndroidJUnit4; 61 62 import com.android.server.uwb.data.UwbRadarData; 63 import com.android.server.uwb.data.UwbRangingData; 64 import com.android.server.uwb.data.UwbUciConstants; 65 import com.android.uwb.flags.Flags; 66 67 import com.google.uwb.support.fira.FiraOnControleeRemovedParams; 68 import com.google.uwb.support.fira.FiraOpenSessionParams; 69 import com.google.uwb.support.fira.FiraParams; 70 import com.google.uwb.support.radar.RadarData; 71 import com.google.uwb.support.radar.RadarOpenSessionParams; 72 import com.google.uwb.support.radar.RadarParams; 73 74 import org.junit.After; 75 import org.junit.Before; 76 import org.junit.Rule; 77 import org.junit.Test; 78 import org.junit.runner.RunWith; 79 import org.mockito.ArgumentCaptor; 80 import org.mockito.Mock; 81 import org.mockito.MockitoAnnotations; 82 83 import java.util.Set; 84 85 /** 86 * Unit tests for {@link com.android.server.uwb.UwbSettingsStore}. 87 */ 88 @RunWith(AndroidJUnit4.class) 89 @SmallTest 90 @Presubmit 91 public class UwbSessionNotificationManagerTest { 92 private static final long TEST_ELAPSED_NANOS = 100L; 93 private static final int UID = 343453; 94 private static final String PACKAGE_NAME = "com.uwb.test"; 95 private static final AttributionSource ATTRIBUTION_SOURCE = 96 new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build(); 97 98 @Mock private UwbInjector mUwbInjector; 99 @Mock private UwbSessionManager.UwbSession mUwbSession; 100 @Mock private UwbSessionManager.UwbSession mUwbRadarSession; 101 @Mock private SessionHandle mSessionHandle; 102 @Mock private IUwbRangingCallbacks mIUwbRangingCallbacks; 103 @Mock private FiraOpenSessionParams mFiraParams; 104 @Mock private RadarOpenSessionParams mRadarParams; 105 @Mock private UwbServiceCore mUwbServiceCore; 106 @Mock private UwbMetrics mUwbMetrics; 107 @Mock private IUwbOemExtensionCallback mIOemExtensionCallback; 108 @Rule 109 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 110 111 private UwbSessionNotificationManager mUwbSessionNotificationManager; 112 113 @Before setUp()114 public void setUp() throws Exception { 115 MockitoAnnotations.initMocks(this); 116 when(mUwbSession.getSessionHandle()).thenReturn(mSessionHandle); 117 when(mUwbSession.getIUwbRangingCallbacks()).thenReturn(mIUwbRangingCallbacks); 118 when(mUwbSession.getProtocolName()).thenReturn(FiraParams.PROTOCOL_NAME); 119 when(mUwbSession.getParams()).thenReturn(mFiraParams); 120 when(mUwbSession.getAttributionSource()).thenReturn(ATTRIBUTION_SOURCE); 121 when(mUwbRadarSession.getSessionHandle()).thenReturn(mSessionHandle); 122 when(mUwbRadarSession.getIUwbRangingCallbacks()).thenReturn(mIUwbRangingCallbacks); 123 when(mUwbRadarSession.getProtocolName()).thenReturn(RadarParams.PROTOCOL_NAME); 124 when(mUwbRadarSession.getParams()).thenReturn(mRadarParams); 125 when(mUwbRadarSession.getAttributionSource()).thenReturn(ATTRIBUTION_SOURCE); 126 when(mFiraParams.getAoaResultRequest()).thenReturn( 127 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS); 128 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(false); 129 when(mFiraParams.hasControlMessage()).thenReturn(false); 130 when(mFiraParams.hasRangingControlPhase()).thenReturn(true); 131 when(mUwbInjector.checkUwbRangingPermissionForStartDataDelivery(any(), any())) 132 .thenReturn(true); 133 when(mUwbInjector.getElapsedSinceBootNanos()).thenReturn(TEST_ELAPSED_NANOS); 134 when(mUwbInjector.getUwbServiceCore()).thenReturn(mUwbServiceCore); 135 when(mUwbServiceCore.isOemExtensionCbRegistered()).thenReturn(true); 136 when(mUwbServiceCore.getOemExtensionCallback()).thenReturn(mIOemExtensionCallback); 137 when(mIOemExtensionCallback.onRangingReportReceived(any())).thenAnswer( 138 invocation -> invocation.getArgument(0)); 139 when(mUwbInjector.getUwbMetrics()).thenReturn(mUwbMetrics); 140 mUwbSessionNotificationManager = new UwbSessionNotificationManager(mUwbInjector); 141 } 142 143 /** 144 * Called after each testGG 145 */ 146 @After cleanup()147 public void cleanup() { 148 validateMockitoUsage(); 149 } 150 151 @Test testOnRangingResultWithoutUwbRangingPermission()152 public void testOnRangingResultWithoutUwbRangingPermission() throws Exception { 153 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 154 UwbTestUtils.generateRangingDataAndRangingReport( 155 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 156 RANGING_MEASUREMENT_TYPE_TWO_WAY, 157 true, true, false, false, TEST_ELAPSED_NANOS); 158 when(mUwbInjector.checkUwbRangingPermissionForStartDataDelivery(eq(ATTRIBUTION_SOURCE), 159 any())).thenReturn(false); 160 when(mUwbSession.isDataDeliveryPermissionCheckNeeded()).thenReturn(true); 161 mUwbSessionNotificationManager.onRangingResult( 162 mUwbSession, testRangingDataAndRangingReport.first); 163 164 verify(mIUwbRangingCallbacks, never()).onRangingResult(any(), any()); 165 verify(mUwbMetrics, never()).logRangingResult(anyInt(), any(), any()); 166 } 167 168 @Test testOnRangingResult_forTwoWay_WithAoa()169 public void testOnRangingResult_forTwoWay_WithAoa() throws Exception { 170 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 171 UwbTestUtils.generateRangingDataAndRangingReport( 172 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 173 RANGING_MEASUREMENT_TYPE_TWO_WAY, 174 true, true, false, false, TEST_ELAPSED_NANOS); 175 mUwbSessionNotificationManager.onRangingResult( 176 mUwbSession, testRangingDataAndRangingReport.first); 177 verify(mIUwbRangingCallbacks).onRangingResult( 178 mSessionHandle, testRangingDataAndRangingReport.second); 179 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 180 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 181 } 182 183 @Test testOnRangingResult_forTwoWay_WithNoAoa()184 public void testOnRangingResult_forTwoWay_WithNoAoa() throws Exception { 185 when(mFiraParams.getAoaResultRequest()).thenReturn( 186 FiraParams.AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT); 187 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 188 UwbTestUtils.generateRangingDataAndRangingReport( 189 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 190 RANGING_MEASUREMENT_TYPE_TWO_WAY, 191 false, false, false, false, TEST_ELAPSED_NANOS); 192 mUwbSessionNotificationManager.onRangingResult( 193 mUwbSession, testRangingDataAndRangingReport.first); 194 verify(mIUwbRangingCallbacks).onRangingResult( 195 mSessionHandle, testRangingDataAndRangingReport.second); 196 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 197 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 198 } 199 200 @Test testOnRangingResult_forTwoWay_WithNoAoaElevation()201 public void testOnRangingResult_forTwoWay_WithNoAoaElevation() throws Exception { 202 when(mFiraParams.getAoaResultRequest()).thenReturn( 203 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_AZIMUTH_ONLY); 204 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 205 UwbTestUtils.generateRangingDataAndRangingReport( 206 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 207 RANGING_MEASUREMENT_TYPE_TWO_WAY, 208 true, false, false, false, TEST_ELAPSED_NANOS); 209 mUwbSessionNotificationManager.onRangingResult( 210 mUwbSession, testRangingDataAndRangingReport.first); 211 verify(mIUwbRangingCallbacks).onRangingResult( 212 mSessionHandle, testRangingDataAndRangingReport.second); 213 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 214 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 215 } 216 217 @Test testOnRangingResult_forTwoWay_WithNoAoaAzimuth()218 public void testOnRangingResult_forTwoWay_WithNoAoaAzimuth() throws Exception { 219 when(mFiraParams.getAoaResultRequest()).thenReturn( 220 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_ELEVATION_ONLY); 221 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 222 UwbTestUtils.generateRangingDataAndRangingReport( 223 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 224 RANGING_MEASUREMENT_TYPE_TWO_WAY, 225 false, true, false, false, TEST_ELAPSED_NANOS); 226 mUwbSessionNotificationManager.onRangingResult( 227 mUwbSession, testRangingDataAndRangingReport.first); 228 verify(mIUwbRangingCallbacks).onRangingResult( 229 mSessionHandle, testRangingDataAndRangingReport.second); 230 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 231 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 232 } 233 234 @Test testOnRangingResult_forTwoWay_WithAoaAndDestAoa()235 public void testOnRangingResult_forTwoWay_WithAoaAndDestAoa() throws Exception { 236 when(mFiraParams.getAoaResultRequest()).thenReturn( 237 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS); 238 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 239 when(mFiraParams.hasControlMessage()).thenReturn(true); 240 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 241 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(true); 242 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(true); 243 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 244 UwbTestUtils.generateRangingDataAndRangingReport( 245 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 246 RANGING_MEASUREMENT_TYPE_TWO_WAY, 247 true, true, true, true, TEST_ELAPSED_NANOS); 248 mUwbSessionNotificationManager.onRangingResult( 249 mUwbSession, testRangingDataAndRangingReport.first); 250 verify(mIUwbRangingCallbacks).onRangingResult( 251 mSessionHandle, testRangingDataAndRangingReport.second); 252 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 253 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 254 } 255 256 @Test testOnRangingResult_forTwoWay_WithAoaAndNoDestAzimuth()257 public void testOnRangingResult_forTwoWay_WithAoaAndNoDestAzimuth() throws Exception { 258 when(mFiraParams.getAoaResultRequest()).thenReturn( 259 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS); 260 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 261 when(mFiraParams.hasControlMessage()).thenReturn(true); 262 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 263 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(false); 264 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(true); 265 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 266 UwbTestUtils.generateRangingDataAndRangingReport( 267 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 268 RANGING_MEASUREMENT_TYPE_TWO_WAY, 269 true, true, false, true, TEST_ELAPSED_NANOS); 270 mUwbSessionNotificationManager.onRangingResult( 271 mUwbSession, testRangingDataAndRangingReport.first); 272 verify(mIUwbRangingCallbacks).onRangingResult( 273 mSessionHandle, testRangingDataAndRangingReport.second); 274 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 275 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 276 } 277 278 @Test testOnRangingResult_forTwoWay_WithAoaAndNoDestElevation()279 public void testOnRangingResult_forTwoWay_WithAoaAndNoDestElevation() throws Exception { 280 when(mFiraParams.getAoaResultRequest()).thenReturn( 281 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS); 282 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 283 when(mFiraParams.hasControlMessage()).thenReturn(true); 284 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 285 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(true); 286 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(false); 287 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 288 UwbTestUtils.generateRangingDataAndRangingReport( 289 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 290 RANGING_MEASUREMENT_TYPE_TWO_WAY, 291 true, true, true, false, TEST_ELAPSED_NANOS); 292 mUwbSessionNotificationManager.onRangingResult( 293 mUwbSession, testRangingDataAndRangingReport.first); 294 verify(mIUwbRangingCallbacks).onRangingResult( 295 mSessionHandle, testRangingDataAndRangingReport.second); 296 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 297 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 298 } 299 300 @Test testOnRangingResult_forTwoWay_WithNoAoaAndDestAoa()301 public void testOnRangingResult_forTwoWay_WithNoAoaAndDestAoa() throws Exception { 302 when(mFiraParams.getAoaResultRequest()).thenReturn( 303 FiraParams.AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT); 304 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 305 when(mFiraParams.hasControlMessage()).thenReturn(true); 306 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 307 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(true); 308 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(true); 309 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 310 UwbTestUtils.generateRangingDataAndRangingReport( 311 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 312 RANGING_MEASUREMENT_TYPE_TWO_WAY, 313 false, false, true, true, TEST_ELAPSED_NANOS); 314 mUwbSessionNotificationManager.onRangingResult( 315 mUwbSession, testRangingDataAndRangingReport.first); 316 verify(mIUwbRangingCallbacks).onRangingResult( 317 mSessionHandle, testRangingDataAndRangingReport.second); 318 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 319 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 320 } 321 322 @Test testOnRangingResult_forTwoWay_WithNoAoaAzimuthAndDestAoa()323 public void testOnRangingResult_forTwoWay_WithNoAoaAzimuthAndDestAoa() throws Exception { 324 when(mFiraParams.getAoaResultRequest()).thenReturn( 325 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_ELEVATION_ONLY); 326 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 327 when(mFiraParams.hasControlMessage()).thenReturn(true); 328 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 329 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(true); 330 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(true); 331 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 332 UwbTestUtils.generateRangingDataAndRangingReport( 333 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 334 RANGING_MEASUREMENT_TYPE_TWO_WAY, 335 false, true, true, true, TEST_ELAPSED_NANOS); 336 mUwbSessionNotificationManager.onRangingResult( 337 mUwbSession, testRangingDataAndRangingReport.first); 338 verify(mIUwbRangingCallbacks).onRangingResult( 339 mSessionHandle, testRangingDataAndRangingReport.second); 340 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 341 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 342 } 343 344 @Test testOnRangingResult_forTwoWay_WithNoAoaElevationAndDestAoa()345 public void testOnRangingResult_forTwoWay_WithNoAoaElevationAndDestAoa() throws Exception { 346 when(mFiraParams.getAoaResultRequest()).thenReturn( 347 FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_AZIMUTH_ONLY); 348 when(mFiraParams.hasRangingResultReportMessage()).thenReturn(true); 349 when(mFiraParams.hasControlMessage()).thenReturn(true); 350 when(mFiraParams.hasRangingControlPhase()).thenReturn(false); 351 when(mFiraParams.hasAngleOfArrivalAzimuthReport()).thenReturn(true); 352 when(mFiraParams.hasAngleOfArrivalElevationReport()).thenReturn(true); 353 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 354 UwbTestUtils.generateRangingDataAndRangingReport( 355 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 356 RANGING_MEASUREMENT_TYPE_TWO_WAY, 357 true, false, true, true, TEST_ELAPSED_NANOS); 358 mUwbSessionNotificationManager.onRangingResult( 359 mUwbSession, testRangingDataAndRangingReport.first); 360 verify(mIUwbRangingCallbacks).onRangingResult( 361 mSessionHandle, testRangingDataAndRangingReport.second); 362 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 363 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 364 } 365 366 @Test testOnRangingResult_forOwrAoa()367 public void testOnRangingResult_forOwrAoa() throws Exception { 368 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 369 UwbTestUtils.generateRangingDataAndRangingReport( 370 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 371 RANGING_MEASUREMENT_TYPE_OWR_AOA, 372 true, true, false, false, TEST_ELAPSED_NANOS); 373 mUwbSessionNotificationManager.onRangingResult( 374 mUwbSession, testRangingDataAndRangingReport.first); 375 verify(mIUwbRangingCallbacks).onRangingResult( 376 mSessionHandle, testRangingDataAndRangingReport.second); 377 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 378 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 379 } 380 381 @Test testOnRangingResult_forDlTDoA()382 public void testOnRangingResult_forDlTDoA() throws Exception { 383 Pair<UwbRangingData, RangingReport> testRangingDataAndRangingReport = 384 UwbTestUtils.generateRangingDataAndRangingReport( 385 PEER_SHORT_MAC_ADDRESS, MAC_ADDRESSING_MODE_SHORT, 386 RANGING_MEASUREMENT_TYPE_DL_TDOA, 387 true, true, false, false, TEST_ELAPSED_NANOS); 388 mUwbSessionNotificationManager.onRangingResult( 389 mUwbSession, testRangingDataAndRangingReport.first); 390 verify(mIUwbRangingCallbacks).onRangingResult( 391 mSessionHandle, testRangingDataAndRangingReport.second); 392 verify(mUwbMetrics).logRangingResult(anyInt(), eq(testRangingDataAndRangingReport.first), 393 eq(testRangingDataAndRangingReport.second.getMeasurements().get(0))); 394 } 395 396 @Test testOnRangingResult_badRangingDataForOwrAoa()397 public void testOnRangingResult_badRangingDataForOwrAoa() throws Exception { 398 UwbRangingData testRangingData = UwbTestUtils.generateBadOwrAoaMeasurementRangingData( 399 MAC_ADDRESSING_MODE_SHORT, PEER_SHORT_MAC_ADDRESS); 400 mUwbSessionNotificationManager.onRangingResult(mUwbSession, testRangingData); 401 verifyZeroInteractions(mIUwbRangingCallbacks); 402 } 403 404 @Test testOnRangingOpened()405 public void testOnRangingOpened() throws Exception { 406 mUwbSessionNotificationManager.onRangingOpened(mUwbSession); 407 408 verify(mIUwbRangingCallbacks).onRangingOpened(mSessionHandle); 409 } 410 411 @Test testOnRangingOpenFailed()412 public void testOnRangingOpenFailed() throws Exception { 413 int status = UwbUciConstants.STATUS_CODE_ERROR_MAX_SESSIONS_EXCEEDED; 414 mUwbSessionNotificationManager.onRangingOpenFailed(mUwbSession, status); 415 416 verify(mIUwbRangingCallbacks).onRangingOpenFailed(eq(mSessionHandle), 417 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 418 argThat(p -> (p.getInt("status_code")) == status)); 419 } 420 421 @Test testOnRangingStarted()422 public void testOnRangingStarted() throws Exception { 423 mUwbSessionNotificationManager.onRangingStarted(mUwbSession, mUwbSession.getParams()); 424 425 verify(mIUwbRangingCallbacks).onRangingStarted(mSessionHandle, 426 mUwbSession.getParams().toBundle()); 427 } 428 429 @Test testOnRangingStartFailed()430 public void testOnRangingStartFailed() throws Exception { 431 int status = UwbUciConstants.STATUS_CODE_INVALID_PARAM; 432 mUwbSessionNotificationManager.onRangingStartFailed(mUwbSession, status); 433 434 verify(mIUwbRangingCallbacks).onRangingStartFailed(eq(mSessionHandle), 435 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 436 argThat(p -> (p.getInt("status_code")) == status)); 437 } 438 439 @Test testOnRangingStartFailedWithUciReasonCode()440 public void testOnRangingStartFailedWithUciReasonCode() throws Exception { 441 int reasonCode = UwbUciConstants.REASON_ERROR_SESSION_KEY_NOT_FOUND; 442 mUwbSessionNotificationManager.onRangingStartFailedWithUciReasonCode( 443 mUwbSession, reasonCode); 444 445 int expectedStatusCode = UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST; 446 verify(mIUwbRangingCallbacks).onRangingStartFailed(eq(mSessionHandle), 447 eq(RangingChangeReason.PROTOCOL_SPECIFIC), 448 argThat(p -> (p.getInt("status_code")) == expectedStatusCode)); 449 } 450 451 @Test testOnRangingStoppedWithUciReasonCode_reasonLocalApi()452 public void testOnRangingStoppedWithUciReasonCode_reasonLocalApi() throws Exception { 453 int reasonCode = UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS; 454 mUwbSessionNotificationManager.onRangingStoppedWithUciReasonCode(mUwbSession, reasonCode); 455 456 verify(mIUwbRangingCallbacks).onRangingStopped( 457 eq(mSessionHandle), eq(RangingChangeReason.LOCAL_API), 458 isA(PersistableBundle.class)); 459 } 460 @Test testOnRangingStoppedWithUciReasonCode_reasonMaxRRRetryReached()461 public void testOnRangingStoppedWithUciReasonCode_reasonMaxRRRetryReached() throws Exception { 462 int reasonCode = UwbUciConstants.REASON_MAX_RANGING_ROUND_RETRY_COUNT_REACHED; 463 mUwbSessionNotificationManager.onRangingStoppedWithUciReasonCode(mUwbSession, reasonCode); 464 465 verify(mIUwbRangingCallbacks).onRangingStopped( 466 eq(mSessionHandle), eq(RangingChangeReason.MAX_RR_RETRY_REACHED), 467 isA(PersistableBundle.class)); 468 } 469 470 @Test testOnRangingStoppedWithUciReasonCode_reasonRemoteRequest()471 public void testOnRangingStoppedWithUciReasonCode_reasonRemoteRequest() throws Exception { 472 int reasonCode = UwbUciConstants.REASON_MAX_NUMBER_OF_MEASUREMENTS_REACHED; 473 mUwbSessionNotificationManager.onRangingStoppedWithUciReasonCode(mUwbSession, reasonCode); 474 475 verify(mIUwbRangingCallbacks).onRangingStopped( 476 eq(mSessionHandle), eq(RangingChangeReason.REMOTE_REQUEST), 477 isA(PersistableBundle.class)); 478 } 479 480 @Test testOnRangingStoppedWithUciReasonCode_reasonBadParameters()481 public void testOnRangingStoppedWithUciReasonCode_reasonBadParameters() throws Exception { 482 Set<Integer> reasonCodes = Set.of( 483 UwbUciConstants.REASON_ERROR_INSUFFICIENT_SLOTS_PER_RR, 484 UwbUciConstants.REASON_ERROR_SLOT_LENGTH_NOT_SUPPORTED, 485 UwbUciConstants.REASON_ERROR_INVALID_UL_TDOA_RANDOM_WINDOW, 486 UwbUciConstants.REASON_ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED, 487 UwbUciConstants.REASON_ERROR_INVALID_RANGING_INTERVAL, 488 UwbUciConstants.REASON_ERROR_INVALID_STS_CONFIG, 489 UwbUciConstants.REASON_ERROR_INVALID_RFRAME_CONFIG, 490 UwbUciConstants.REASON_ERROR_HUS_NOT_ENOUGH_SLOTS, 491 UwbUciConstants.REASON_ERROR_HUS_CFP_PHASE_TOO_SHORT, 492 UwbUciConstants.REASON_ERROR_HUS_CAP_PHASE_TOO_SHORT, 493 UwbUciConstants.REASON_ERROR_HUS_OTHERS); 494 for (int reasonCode : reasonCodes) { 495 clearInvocations(mIUwbRangingCallbacks); 496 mUwbSessionNotificationManager.onRangingStoppedWithUciReasonCode(mUwbSession, 497 reasonCode); 498 verify(mIUwbRangingCallbacks).onRangingStopped( 499 eq(mSessionHandle), eq(RangingChangeReason.BAD_PARAMETERS), 500 isA(PersistableBundle.class)); 501 } 502 } 503 504 @Test testOnRangingStoppedWithUciReasonCode_reasonSystemRegulation()505 public void testOnRangingStoppedWithUciReasonCode_reasonSystemRegulation() throws Exception { 506 int reasonCode = UwbUciConstants.REASON_REGULATION_UWB_OFF; 507 mUwbSessionNotificationManager.onRangingStoppedWithUciReasonCode(mUwbSession, reasonCode); 508 509 verify(mIUwbRangingCallbacks).onRangingStopped( 510 eq(mSessionHandle), eq(RangingChangeReason.SYSTEM_REGULATION), 511 isA(PersistableBundle.class)); 512 } 513 514 @Test testOnRangingStoppedWithApiReasonCode()515 public void testOnRangingStoppedWithApiReasonCode() throws Exception { 516 mUwbSessionNotificationManager.onRangingStoppedWithApiReasonCode( 517 mUwbSession, RangingChangeReason.SYSTEM_POLICY, new PersistableBundle()); 518 519 verify(mIUwbRangingCallbacks).onRangingStopped( 520 eq(mSessionHandle), eq(RangingChangeReason.SYSTEM_POLICY), 521 isA(PersistableBundle.class)); 522 } 523 524 @Test testOnRangingStopped()525 public void testOnRangingStopped() throws Exception { 526 int status = UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS; 527 mUwbSessionNotificationManager.onRangingStopped(mUwbSession, status); 528 529 verify(mIUwbRangingCallbacks).onRangingStopped(eq(mSessionHandle), 530 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 531 argThat(p-> p.getInt("status_code") == status)); 532 } 533 534 @Test 535 @RequiresFlagsEnabled(Flags.FLAG_REASON_INBAND_SESSION_STOP) testRangingStoppedDuetoInbandSignal()536 public void testRangingStoppedDuetoInbandSignal() throws Exception { 537 mUwbSessionNotificationManager.onRangingStoppedWithApiReasonCode(mUwbSession, 538 RangingChangeReason.INBAND_SESSION_STOP, new PersistableBundle()); 539 540 verify(mIUwbRangingCallbacks).onRangingStopped( 541 eq(mSessionHandle), eq(RangingChangeReason.INBAND_SESSION_STOP), 542 isA(PersistableBundle.class)); 543 } 544 545 @Test testOnRangingStopFailed()546 public void testOnRangingStopFailed() throws Exception { 547 int status = UwbUciConstants.STATUS_CODE_INVALID_RANGE; 548 mUwbSessionNotificationManager.onRangingStopFailed(mUwbSession, status); 549 550 verify(mIUwbRangingCallbacks).onRangingStopFailed(eq(mSessionHandle), 551 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 552 argThat(p -> (p.getInt("status_code")) == status)); 553 } 554 555 @Test testOnRangingReconfigured()556 public void testOnRangingReconfigured() throws Exception { 557 mUwbSessionNotificationManager.onRangingReconfigured(mUwbSession); 558 559 verify(mIUwbRangingCallbacks).onRangingReconfigured(eq(mSessionHandle), any()); 560 } 561 562 @Test testOnRangingReconfigureFailed()563 public void testOnRangingReconfigureFailed() throws Exception { 564 int status = UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE; 565 mUwbSessionNotificationManager.onRangingReconfigureFailed(mUwbSession, status); 566 567 verify(mIUwbRangingCallbacks).onRangingReconfigureFailed(eq(mSessionHandle), 568 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 569 argThat(p -> (p.getInt("status_code")) == status)); 570 } 571 572 @Test testOnControleeAdded()573 public void testOnControleeAdded() throws Exception { 574 mUwbSessionNotificationManager.onControleeAdded(mUwbSession); 575 576 verify(mIUwbRangingCallbacks).onControleeAdded(eq(mSessionHandle), any()); 577 } 578 579 @Test testOnControleeAddFailed()580 public void testOnControleeAddFailed() throws Exception { 581 int status = UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE; 582 mUwbSessionNotificationManager.onControleeAddFailed(mUwbSession, status); 583 584 verify(mIUwbRangingCallbacks).onControleeAddFailed(eq(mSessionHandle), 585 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 586 argThat(p -> (p.getInt("status_code")) == status)); 587 } 588 589 @Test testOnControleeRemoved()590 public void testOnControleeRemoved() throws Exception { 591 UwbAddress address = UwbTestUtils.PEER_EXTENDED_UWB_ADDRESS; 592 int reason = FiraOnControleeRemovedParams.Reason.LOST_CONNECTION; 593 594 ArgumentCaptor<PersistableBundle> bundleCaptor = 595 ArgumentCaptor.forClass(PersistableBundle.class); 596 597 mUwbSessionNotificationManager.onControleeRemoved(mUwbSession, address, reason); 598 verify(mIUwbRangingCallbacks).onControleeRemoved(eq(mSessionHandle), 599 bundleCaptor.capture()); 600 601 FiraOnControleeRemovedParams params = 602 FiraOnControleeRemovedParams.fromBundle(bundleCaptor.getValue()); 603 assertThat(params.getAddress()).isEqualTo(address); 604 assertThat(params.getReason()).isEqualTo(reason); 605 } 606 607 @Test testOnControleeRemoveFailed()608 public void testOnControleeRemoveFailed() throws Exception { 609 int status = UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE; 610 mUwbSessionNotificationManager.onControleeRemoveFailed(mUwbSession, status); 611 612 verify(mIUwbRangingCallbacks).onControleeRemoveFailed(eq(mSessionHandle), 613 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 614 argThat(p -> (p.getInt("status_code")) == status)); 615 } 616 617 @Test testOnRangingClosed()618 public void testOnRangingClosed() throws Exception { 619 int status = UwbUciConstants.REASON_ERROR_SLOT_LENGTH_NOT_SUPPORTED; 620 mUwbSessionNotificationManager.onRangingClosed(mUwbSession, status); 621 622 verify(mIUwbRangingCallbacks).onRangingClosed(eq(mSessionHandle), 623 eq(UwbSessionNotificationHelper.convertUciStatusToApiReasonCode(status)), 624 argThat(p-> p.getInt("status_code") == status)); 625 } 626 627 @Test testOnRangingClosedWithReasonCode()628 public void testOnRangingClosedWithReasonCode() throws Exception { 629 int reasonCode = RangingChangeReason.SYSTEM_POLICY; 630 mUwbSessionNotificationManager.onRangingClosedWithApiReasonCode(mUwbSession, reasonCode); 631 632 verify(mIUwbRangingCallbacks).onRangingClosed(eq(mSessionHandle), 633 eq(reasonCode), 634 argThat(p-> p.isEmpty())); 635 } 636 637 @Test testOnDataReceived()638 public void testOnDataReceived() throws Exception { 639 mUwbSessionNotificationManager.onDataReceived(mUwbSession, PEER_EXTENDED_UWB_ADDRESS, 640 PERSISTABLE_BUNDLE, DATA_PAYLOAD); 641 642 verify(mIUwbRangingCallbacks).onDataReceived(eq(mSessionHandle), eq( 643 PEER_EXTENDED_UWB_ADDRESS), 644 eq(PERSISTABLE_BUNDLE), eq(DATA_PAYLOAD)); 645 } 646 647 @Test testOnDataReceiveFailed()648 public void testOnDataReceiveFailed() throws Exception { 649 mUwbSessionNotificationManager.onDataReceiveFailed(mUwbSession, PEER_EXTENDED_UWB_ADDRESS, 650 STATUS_CODE_FAILED, PERSISTABLE_BUNDLE); 651 652 verify(mIUwbRangingCallbacks).onDataReceiveFailed(eq(mSessionHandle), eq( 653 PEER_EXTENDED_UWB_ADDRESS), 654 eq(STATUS_CODE_FAILED), eq(PERSISTABLE_BUNDLE)); 655 } 656 657 @Test testOnDataSent()658 public void testOnDataSent() throws Exception { 659 mUwbSessionNotificationManager.onDataSent(mUwbSession, PEER_EXTENDED_UWB_ADDRESS, 660 PERSISTABLE_BUNDLE); 661 662 verify(mIUwbRangingCallbacks).onDataSent(eq(mSessionHandle), eq(PEER_EXTENDED_UWB_ADDRESS), 663 eq(PERSISTABLE_BUNDLE)); 664 } 665 666 @Test testOnDataSendFailed()667 public void testOnDataSendFailed() throws Exception { 668 mUwbSessionNotificationManager.onDataSendFailed(mUwbSession, PEER_EXTENDED_UWB_ADDRESS, 669 STATUS_CODE_FAILED, PERSISTABLE_BUNDLE); 670 671 verify(mIUwbRangingCallbacks).onDataSendFailed(eq(mSessionHandle), eq( 672 PEER_EXTENDED_UWB_ADDRESS), 673 eq(STATUS_CODE_FAILED), eq(PERSISTABLE_BUNDLE)); 674 } 675 676 @Test testOnDataTransferPhaseConfigured()677 public void testOnDataTransferPhaseConfigured() throws Exception { 678 int dataTransferPhaseConfigStatus = 679 UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_DTPCM_CONFIG_SUCCESS; 680 mUwbSessionNotificationManager.onDataTransferPhaseConfigured(mUwbSession, 681 dataTransferPhaseConfigStatus); 682 683 verify(mIUwbRangingCallbacks).onDataTransferPhaseConfigured(eq(mSessionHandle), 684 argThat(p -> (p.getInt("data_transfer_phase_config_status_code")) 685 == dataTransferPhaseConfigStatus)); 686 } 687 688 @Test testOnDataTransferPhaseConfigFailed()689 public void testOnDataTransferPhaseConfigFailed() throws Exception { 690 int dataTransferPhaseConfigStatus = 691 UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_ERROR_DUPLICATE_SLOT_ASSIGNMENT; 692 mUwbSessionNotificationManager.onDataTransferPhaseConfigFailed(mUwbSession, 693 dataTransferPhaseConfigStatus); 694 695 verify(mIUwbRangingCallbacks).onDataTransferPhaseConfigFailed(eq(mSessionHandle), 696 eq(RangingChangeReason.PROTOCOL_SPECIFIC), 697 argThat(p -> (p.getInt("data_transfer_phase_config_status_code")) 698 == dataTransferPhaseConfigStatus)); 699 } 700 701 @Test testOnHybridSessionControllerConfigured()702 public void testOnHybridSessionControllerConfigured() throws Exception { 703 mUwbSessionNotificationManager.onHybridSessionControllerConfigured(mUwbSession, 704 UwbUciConstants.STATUS_CODE_OK); 705 706 verify(mIUwbRangingCallbacks).onHybridSessionControllerConfigured(eq(mSessionHandle), 707 argThat(p -> (p.getInt("status_code")) == UwbUciConstants.STATUS_CODE_OK)); 708 } 709 710 @Test testOnHybridSessionControllerConfigurationFailed()711 public void testOnHybridSessionControllerConfigurationFailed() throws Exception { 712 mUwbSessionNotificationManager.onHybridSessionControllerConfigurationFailed(mUwbSession, 713 UwbUciConstants.STATUS_CODE_FAILED); 714 715 verify(mIUwbRangingCallbacks).onHybridSessionControllerConfigurationFailed( 716 eq(mSessionHandle), 717 eq(RangingChangeReason.UNKNOWN), 718 argThat(p -> (p.getInt("status_code")) == UwbUciConstants.STATUS_CODE_FAILED)); 719 } 720 721 @Test testOnHybridSessionControleeConfigured()722 public void testOnHybridSessionControleeConfigured() throws Exception { 723 mUwbSessionNotificationManager.onHybridSessionControleeConfigured(mUwbSession, 724 UwbUciConstants.STATUS_CODE_OK); 725 726 verify(mIUwbRangingCallbacks).onHybridSessionControleeConfigured(eq(mSessionHandle), 727 argThat(p -> (p.getInt("status_code")) == UwbUciConstants.STATUS_CODE_OK)); 728 } 729 730 @Test testOnHybridSessionControleeConfigurationFailed()731 public void testOnHybridSessionControleeConfigurationFailed() throws Exception { 732 mUwbSessionNotificationManager.onHybridSessionControleeConfigurationFailed(mUwbSession, 733 UwbUciConstants.STATUS_CODE_FAILED); 734 735 verify(mIUwbRangingCallbacks).onHybridSessionControleeConfigurationFailed( 736 eq(mSessionHandle), 737 eq(RangingChangeReason.UNKNOWN), 738 argThat(p -> (p.getInt("status_code")) == UwbUciConstants.STATUS_CODE_FAILED)); 739 } 740 741 @Test testOnRangingRoundsUpdateStatus()742 public void testOnRangingRoundsUpdateStatus() throws RemoteException { 743 PersistableBundle bundle = new PersistableBundle(); 744 mUwbSessionNotificationManager.onRangingRoundsUpdateStatus(mUwbSession, bundle); 745 746 verify(mIUwbRangingCallbacks).onRangingRoundsUpdateDtTagStatus(eq(mSessionHandle), 747 eq(bundle)); 748 } 749 750 @Test testonRadarDataMessageReceivedWithoutUwbRangingPermission()751 public void testonRadarDataMessageReceivedWithoutUwbRangingPermission() throws Exception { 752 Pair<UwbRadarData, RadarData> testUwbRadarDataAndRadarData = 753 UwbTestUtils.generateUwbRadarDataAndRadarData( 754 RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES); 755 when(mUwbInjector.checkUwbRangingPermissionForStartDataDelivery(eq(ATTRIBUTION_SOURCE), 756 any())).thenReturn(false); 757 when(mUwbRadarSession.isDataDeliveryPermissionCheckNeeded()).thenReturn(true); 758 mUwbSessionNotificationManager.onRadarDataMessageReceived( 759 mUwbRadarSession, testUwbRadarDataAndRadarData.first); 760 761 verify(mIUwbRangingCallbacks, never()).onDataReceived(any(), any(), any(), any()); 762 } 763 764 @Test testonRadarDataMessageReceived_forRadarSweepData()765 public void testonRadarDataMessageReceived_forRadarSweepData() throws Exception { 766 Pair<UwbRadarData, RadarData> testUwbRadarDataAndRadarData = 767 UwbTestUtils.generateUwbRadarDataAndRadarData( 768 RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES); 769 mUwbSessionNotificationManager.onRadarDataMessageReceived( 770 mUwbRadarSession, testUwbRadarDataAndRadarData.first); 771 772 verify(mIUwbRangingCallbacks).onDataReceived( 773 eq(mSessionHandle), 774 eq(UwbAddress.fromBytes(new byte[] {0x00, 0x00})), 775 argThat(p -> p.getInt("sweep_offset") 776 == testUwbRadarDataAndRadarData.second.getSweepOffset()), 777 eq(new byte[] {})); 778 } 779 } 780