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 android.uwb; 18 19 import static android.uwb.RangingSession.Callback.REASON_BAD_PARAMETERS; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertTrue; 26 import static org.junit.Assert.fail; 27 import static org.junit.Assume.assumeTrue; 28 import static org.mockito.ArgumentMatchers.any; 29 import static org.mockito.ArgumentMatchers.anyInt; 30 import static org.mockito.ArgumentMatchers.eq; 31 import static org.mockito.Mockito.doAnswer; 32 import static org.mockito.Mockito.doNothing; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.when; 37 38 import android.content.AttributionSource; 39 import android.os.PersistableBundle; 40 import android.os.Process; 41 import android.os.RemoteException; 42 43 import androidx.test.ext.junit.runners.AndroidJUnit4; 44 import androidx.test.filters.SmallTest; 45 46 import com.android.modules.utils.build.SdkLevel; 47 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.ArgumentCaptor; 51 import org.mockito.invocation.InvocationOnMock; 52 import org.mockito.stubbing.Answer; 53 54 import java.util.concurrent.Executor; 55 56 /** 57 * Test of {@link RangingSession}. 58 */ 59 @SmallTest 60 @RunWith(AndroidJUnit4.class) 61 public class RangingSessionTest { 62 private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); 63 private static final PersistableBundle PARAMS = new PersistableBundle(); 64 private static final UwbAddress UWB_ADDRESS = UwbAddress.fromBytes(new byte[] {0x00, 0x56}); 65 private static final @RangingSession.Callback.Reason int REASON = 66 RangingSession.Callback.REASON_GENERIC_ERROR; 67 private static final int UID = Process.myUid(); 68 private static final String PACKAGE_NAME = "com.uwb.test"; 69 private static final AttributionSource ATTRIBUTION_SOURCE = 70 new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build(); 71 private static final int HANDLE_ID = 12; 72 private static final int PID = Process.myPid(); 73 private static final int MAX_DATA_SIZE = 100; 74 public static final int STATUS_OK = 0; 75 76 @Test testOnRangingOpened_OnOpenSuccessCalled()77 public void testOnRangingOpened_OnOpenSuccessCalled() { 78 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 79 RangingSession.Callback callback = mock(RangingSession.Callback.class); 80 IUwbAdapter adapter = mock(IUwbAdapter.class); 81 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 82 verifyOpenState(session, false); 83 84 session.onRangingOpened(); 85 verifyOpenState(session, true); 86 87 // Verify that the onOpenSuccess callback was invoked 88 verify(callback, times(1)).onOpened(eq(session)); 89 verify(callback, times(0)).onClosed(anyInt(), any()); 90 } 91 92 @Test testOnRangingOpened_OnServiceDiscoveredConnectedCalled()93 public void testOnRangingOpened_OnServiceDiscoveredConnectedCalled() { 94 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 95 RangingSession.Callback callback = mock(RangingSession.Callback.class); 96 IUwbAdapter adapter = mock(IUwbAdapter.class); 97 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 98 verifyOpenState(session, false); 99 100 session.onRangingOpened(); 101 verifyOpenState(session, true); 102 103 // Verify that the onOpenSuccess callback was invoked 104 verify(callback, times(1)).onOpened(eq(session)); 105 verify(callback, times(0)).onClosed(anyInt(), any()); 106 107 session.onServiceDiscovered(PARAMS); 108 verify(callback, times(1)).onServiceDiscovered(eq(PARAMS)); 109 110 session.onServiceConnected(PARAMS); 111 verify(callback, times(1)).onServiceConnected(eq(PARAMS)); 112 } 113 114 115 @Test testOnRangingOpened_CannotOpenClosedSession()116 public void testOnRangingOpened_CannotOpenClosedSession() { 117 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 118 RangingSession.Callback callback = mock(RangingSession.Callback.class); 119 IUwbAdapter adapter = mock(IUwbAdapter.class); 120 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 121 122 session.onRangingOpened(); 123 verifyOpenState(session, true); 124 verify(callback, times(1)).onOpened(eq(session)); 125 verify(callback, times(0)).onClosed(anyInt(), any()); 126 127 session.onRangingClosed(REASON, PARAMS); 128 verifyOpenState(session, false); 129 verify(callback, times(1)).onOpened(eq(session)); 130 verify(callback, times(1)).onClosed(anyInt(), any()); 131 132 // Now invoke the ranging started callback and ensure the session remains closed 133 session.onRangingOpened(); 134 verifyOpenState(session, false); 135 verify(callback, times(1)).onOpened(eq(session)); 136 verify(callback, times(1)).onClosed(anyInt(), any()); 137 } 138 139 @Test testOnRangingClosed_OnClosedCalledWhenSessionNotOpen()140 public void testOnRangingClosed_OnClosedCalledWhenSessionNotOpen() { 141 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 142 RangingSession.Callback callback = mock(RangingSession.Callback.class); 143 IUwbAdapter adapter = mock(IUwbAdapter.class); 144 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 145 verifyOpenState(session, false); 146 147 session.onRangingClosed(REASON, PARAMS); 148 verifyOpenState(session, false); 149 150 // Verify that the onOpenSuccess callback was invoked 151 verify(callback, times(0)).onOpened(eq(session)); 152 verify(callback, times(1)).onClosed(anyInt(), any()); 153 } 154 155 @Test testOnRangingClosed_OnClosedCalled()156 public void testOnRangingClosed_OnClosedCalled() { 157 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 158 RangingSession.Callback callback = mock(RangingSession.Callback.class); 159 IUwbAdapter adapter = mock(IUwbAdapter.class); 160 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 161 session.onRangingStarted(PARAMS); 162 session.onRangingClosed(REASON, PARAMS); 163 verify(callback, times(1)).onClosed(anyInt(), any()); 164 165 verifyOpenState(session, false); 166 session.onRangingClosed(REASON, PARAMS); 167 verify(callback, times(2)).onClosed(anyInt(), any()); 168 } 169 170 @Test testOnRangingResult_OnReportReceivedCalled()171 public void testOnRangingResult_OnReportReceivedCalled() { 172 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 173 RangingSession.Callback callback = mock(RangingSession.Callback.class); 174 IUwbAdapter adapter = mock(IUwbAdapter.class); 175 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 176 verifyOpenState(session, false); 177 178 session.onRangingStarted(PARAMS); 179 verifyOpenState(session, true); 180 181 RangingReport report = UwbTestUtils.getRangingReports(1); 182 session.onRangingResult(report); 183 verify(callback, times(1)).onReportReceived(eq(report)); 184 } 185 186 @Test testStart_CannotStartIfAlreadyStarted()187 public void testStart_CannotStartIfAlreadyStarted() throws RemoteException { 188 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 189 RangingSession.Callback callback = mock(RangingSession.Callback.class); 190 IUwbAdapter adapter = mock(IUwbAdapter.class); 191 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 192 doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); 193 session.onRangingOpened(); 194 195 session.start(PARAMS); 196 verify(callback, times(1)).onStarted(any()); 197 198 // Calling start again should throw an illegal state 199 verifyThrowIllegalState(() -> session.start(PARAMS)); 200 verify(callback, times(1)).onStarted(any()); 201 } 202 203 @Test testStop_CannotStopIfAlreadyStopped()204 public void testStop_CannotStopIfAlreadyStopped() throws RemoteException { 205 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 206 RangingSession.Callback callback = mock(RangingSession.Callback.class); 207 IUwbAdapter adapter = mock(IUwbAdapter.class); 208 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 209 doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); 210 doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any()); 211 session.onRangingOpened(); 212 session.start(PARAMS); 213 214 verifyNoThrowIllegalState(session::stop); 215 verify(callback, times(1)).onStopped(anyInt(), any()); 216 217 // Calling stop again should throw an illegal state 218 verifyThrowIllegalState(session::stop); 219 verify(callback, times(1)).onStopped(anyInt(), any()); 220 } 221 222 @Test testStop_CannotStopIfOpenFailed()223 public void testStop_CannotStopIfOpenFailed() throws RemoteException { 224 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 225 RangingSession.Callback callback = mock(RangingSession.Callback.class); 226 IUwbAdapter adapter = mock(IUwbAdapter.class); 227 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 228 doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); 229 doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any()); 230 session.onRangingOpened(); 231 session.start(PARAMS); 232 233 verifyNoThrowIllegalState(() -> session.onRangingOpenFailed(REASON_BAD_PARAMETERS, PARAMS)); 234 verify(callback, times(1)).onOpenFailed( 235 REASON_BAD_PARAMETERS, PARAMS); 236 237 // Calling stop again should throw an illegal state 238 verifyThrowIllegalState(session::stop); 239 verify(callback, times(0)).onStopped(anyInt(), any()); 240 } 241 242 @Test testCallbacks_OnlyWhenOpened()243 public void testCallbacks_OnlyWhenOpened() throws RemoteException { 244 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 245 RangingSession.Callback callback = mock(RangingSession.Callback.class); 246 IUwbAdapter adapter = mock(IUwbAdapter.class); 247 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 248 doAnswer(new OpenAnswer(session)).when(adapter).openRanging( 249 any(), any(), any(), any(), any()); 250 doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any()); 251 doAnswer(new ReconfigureAnswer(session)).when(adapter).reconfigureRanging(any(), any()); 252 doAnswer(new PauseAnswer(session)).when(adapter).pause(any(), any()); 253 doAnswer(new ResumeAnswer(session)).when(adapter).resume(any(), any()); 254 doAnswer(new ControleeAddAnswer(session)).when(adapter).addControlee(any(), any()); 255 doAnswer(new ControleeRemoveAnswer(session)).when(adapter).removeControlee(any(), any()); 256 doAnswer(new DataSendAnswer(session)).when(adapter).sendData(any(), any(), any(), any()); 257 doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any()); 258 doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any()); 259 doAnswer(new DataTransferPhaseConfigAnswer(session)).when(adapter) 260 .setDataTransferPhaseConfig(any(), any()); 261 doAnswer(new HybridSessionControllerConfigurationAnswer(session)).when(adapter) 262 .setHybridSessionControllerConfiguration(any(), any()); 263 doAnswer(new HybridSessionControleeConfigurationAnswer(session)).when(adapter) 264 .setHybridSessionControleeConfiguration(any(), any()); 265 266 verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); 267 verify(callback, times(0)).onReconfigured(any()); 268 verifyOpenState(session, false); 269 270 session.onRangingOpened(); 271 verifyOpenState(session, true); 272 verify(callback, times(1)).onOpened(any()); 273 verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); 274 verify(callback, times(1)).onReconfigured(any()); 275 verifyThrowIllegalState(() -> session.pause(PARAMS)); 276 verify(callback, times(0)).onPaused(any()); 277 verifyThrowIllegalState(() -> session.resume(PARAMS)); 278 verify(callback, times(0)).onResumed(any()); 279 verifyNoThrowIllegalState(() -> session.addControlee(PARAMS)); 280 verify(callback, times(1)).onControleeAdded(any()); 281 verifyNoThrowIllegalState(() -> session.removeControlee(PARAMS)); 282 verify(callback, times(1)).onControleeRemoved(any()); 283 verifyThrowIllegalState(() -> session.sendData( 284 UWB_ADDRESS, PARAMS, new byte[] {0x05, 0x1})); 285 verify(callback, times(0)).onDataSent(any(), any()); 286 287 session.onRangingStartFailed(REASON_BAD_PARAMETERS, PARAMS); 288 verifyOpenState(session, true); 289 verify(callback, times(1)).onStartFailed( 290 REASON_BAD_PARAMETERS, PARAMS); 291 292 session.onRangingStarted(PARAMS); 293 verifyOpenState(session, true); 294 verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); 295 verify(callback, times(2)).onReconfigured(any()); 296 verifyNoThrowIllegalState(() -> session.reconfigure(null)); 297 verify(callback, times(1)).onReconfigureFailed( 298 eq(REASON_BAD_PARAMETERS), any()); 299 verifyNoThrowIllegalState(() -> session.pause(PARAMS)); 300 verify(callback, times(1)).onPaused(any()); 301 verifyNoThrowIllegalState(() -> session.pause(null)); 302 verify(callback, times(1)).onPauseFailed( 303 eq(REASON_BAD_PARAMETERS), any()); 304 verifyNoThrowIllegalState(() -> session.resume(PARAMS)); 305 verify(callback, times(1)).onResumed(any()); 306 verifyNoThrowIllegalState(() -> session.resume(null)); 307 verify(callback, times(1)).onResumeFailed( 308 eq(REASON_BAD_PARAMETERS), any()); 309 verifyNoThrowIllegalState(() -> session.addControlee(PARAMS)); 310 verify(callback, times(2)).onControleeAdded(any()); 311 verifyNoThrowIllegalState(() -> session.addControlee(null)); 312 verify(callback, times(1)).onControleeAddFailed( 313 eq(REASON_BAD_PARAMETERS), any()); 314 verifyNoThrowIllegalState(() -> session.removeControlee(PARAMS)); 315 verify(callback, times(2)).onControleeRemoved(any()); 316 verifyNoThrowIllegalState(() -> session.removeControlee(null)); 317 verify(callback, times(1)).onControleeRemoveFailed( 318 eq(REASON_BAD_PARAMETERS), any()); 319 verifyNoThrowIllegalState(() -> session.sendData( 320 UWB_ADDRESS, PARAMS, new byte[] {0x05, 0x1})); 321 verify(callback, times(1)).onDataSent(any(), any()); 322 verifyNoThrowIllegalState(() -> session.sendData( 323 null, PARAMS, new byte[] {0x05, 0x1})); 324 verify(callback, times(1)).onDataSendFailed( 325 eq(null), eq(REASON_BAD_PARAMETERS), any()); 326 327 session.onDataReceived(UWB_ADDRESS, PARAMS, new byte[] {0x5, 0x7}); 328 verify(callback, times(1)).onDataReceived( 329 UWB_ADDRESS, PARAMS, new byte[] {0x5, 0x7}); 330 session.onDataReceiveFailed(UWB_ADDRESS, REASON_BAD_PARAMETERS, PARAMS); 331 verify(callback, times(1)).onDataReceiveFailed( 332 UWB_ADDRESS, REASON_BAD_PARAMETERS, PARAMS); 333 334 session.onDataTransferPhaseConfigured(PARAMS); 335 verify(callback, times(1)).onDataTransferPhaseConfigured(any()); 336 session.setDataTransferPhaseConfig(PARAMS); 337 verify(callback, times(2)).onDataTransferPhaseConfigured(any()); 338 339 session.onDataTransferPhaseConfigFailed(REASON_BAD_PARAMETERS, PARAMS); 340 verify(callback, times(1)).onDataTransferPhaseConfigFailed( 341 eq(REASON_BAD_PARAMETERS), eq(PARAMS)); 342 verifyNoThrowIllegalState(() -> session.setDataTransferPhaseConfig(null)); 343 verify(callback, times(1)).onDataTransferPhaseConfigFailed( 344 eq(REASON_BAD_PARAMETERS), eq(null)); 345 346 session.onHybridSessionControllerConfigured(PARAMS); 347 verify(callback, times(1)).onHybridSessionControllerConfigured(any()); 348 session.setHybridSessionControllerConfiguration(PARAMS); 349 verify(callback, times(2)).onHybridSessionControllerConfigured(any()); 350 351 session.onHybridSessionControllerConfigurationFailed(REASON_BAD_PARAMETERS, PARAMS); 352 verify(callback, times(1)).onHybridSessionControllerConfigurationFailed( 353 eq(REASON_BAD_PARAMETERS), eq(PARAMS)); 354 verifyNoThrowIllegalState(() -> session.setHybridSessionControllerConfiguration(null)); 355 verify(callback, times(1)).onHybridSessionControllerConfigurationFailed( 356 eq(REASON_BAD_PARAMETERS), eq(null)); 357 358 session.onHybridSessionControleeConfigured(PARAMS); 359 verify(callback, times(1)).onHybridSessionControleeConfigured(any()); 360 session.setHybridSessionControleeConfiguration(PARAMS); 361 verify(callback, times(2)).onHybridSessionControleeConfigured(any()); 362 363 session.onHybridSessionControleeConfigurationFailed(REASON_BAD_PARAMETERS, PARAMS); 364 verify(callback, times(1)).onHybridSessionControleeConfigurationFailed( 365 eq(REASON_BAD_PARAMETERS), eq(PARAMS)); 366 verifyNoThrowIllegalState(() -> session.setHybridSessionControleeConfiguration(null)); 367 verify(callback, times(1)).onHybridSessionControleeConfigurationFailed( 368 eq(REASON_BAD_PARAMETERS), eq(null)); 369 370 session.stop(); 371 verifyOpenState(session, true); 372 verify(callback, times(1)).onStopped(REASON, PARAMS); 373 374 verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS)); 375 verify(callback, times(3)).onReconfigured(any()); 376 verifyThrowIllegalState(() -> session.pause(PARAMS)); 377 verify(callback, times(1)).onPaused(any()); 378 verifyThrowIllegalState(() -> session.resume(PARAMS)); 379 verify(callback, times(1)).onResumed(any()); 380 verifyNoThrowIllegalState(() -> session.addControlee(PARAMS)); 381 verify(callback, times(3)).onControleeAdded(any()); 382 verifyNoThrowIllegalState(() -> session.removeControlee(PARAMS)); 383 verify(callback, times(3)).onControleeRemoved(any()); 384 verifyThrowIllegalState(() -> session.sendData( 385 UWB_ADDRESS, PARAMS, new byte[] {0x05, 0x1})); 386 verify(callback, times(1)).onDataSent(any(), any()); 387 388 session.close(); 389 verifyOpenState(session, false); 390 verify(callback, times(1)).onClosed(REASON, PARAMS); 391 392 verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); 393 verify(callback, times(3)).onReconfigured(any()); 394 verifyThrowIllegalState(() -> session.pause(PARAMS)); 395 verify(callback, times(1)).onPaused(any()); 396 verifyThrowIllegalState(() -> session.resume(PARAMS)); 397 verify(callback, times(1)).onResumed(any()); 398 verifyThrowIllegalState(() -> session.addControlee(PARAMS)); 399 verify(callback, times(3)).onControleeAdded(any()); 400 verifyThrowIllegalState(() -> session.removeControlee(PARAMS)); 401 verify(callback, times(3)).onControleeRemoved(any()); 402 verifyThrowIllegalState(() -> session.sendData( 403 UWB_ADDRESS, PARAMS, new byte[] {0x05, 0x1})); 404 verify(callback, times(1)).onDataSent(any(), any()); 405 } 406 407 @Test testClose_NoCallbackUntilInvoked()408 public void testClose_NoCallbackUntilInvoked() throws RemoteException { 409 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 410 RangingSession.Callback callback = mock(RangingSession.Callback.class); 411 IUwbAdapter adapter = mock(IUwbAdapter.class); 412 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 413 session.onRangingOpened(); 414 415 // Calling close multiple times should invoke closeRanging until the session receives 416 // the onClosed callback. 417 int totalCallsBeforeOnRangingClosed = 3; 418 for (int i = 1; i <= totalCallsBeforeOnRangingClosed; i++) { 419 session.close(); 420 verifyOpenState(session, true); 421 verify(adapter, times(i)).closeRanging(handle); 422 verify(callback, times(0)).onClosed(anyInt(), any()); 423 } 424 425 // After onClosed is invoked, then the adapter should no longer be called for each call to 426 // the session's close. 427 final int totalCallsAfterOnRangingClosed = 2; 428 for (int i = 1; i <= totalCallsAfterOnRangingClosed; i++) { 429 session.onRangingClosed(REASON, PARAMS); 430 verifyOpenState(session, false); 431 verify(adapter, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle); 432 verify(callback, times(i)).onClosed(anyInt(), any()); 433 } 434 } 435 436 @Test testClose_OnClosedCalled()437 public void testClose_OnClosedCalled() throws RemoteException { 438 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 439 RangingSession.Callback callback = mock(RangingSession.Callback.class); 440 IUwbAdapter adapter = mock(IUwbAdapter.class); 441 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 442 doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any()); 443 session.onRangingOpened(); 444 445 session.close(); 446 verify(callback, times(1)).onClosed(anyInt(), any()); 447 } 448 449 @Test testClose_CannotInteractFurther()450 public void testClose_CannotInteractFurther() throws RemoteException { 451 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 452 RangingSession.Callback callback = mock(RangingSession.Callback.class); 453 IUwbAdapter adapter = mock(IUwbAdapter.class); 454 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 455 doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any()); 456 session.close(); 457 458 verifyThrowIllegalState(() -> session.start(PARAMS)); 459 verifyThrowIllegalState(() -> session.reconfigure(PARAMS)); 460 verifyThrowIllegalState(() -> session.stop()); 461 verifyNoThrowIllegalState(() -> session.close()); 462 } 463 464 @Test testQueryDataSize()465 public void testQueryDataSize() throws RemoteException { 466 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 467 RangingSession.Callback callback = mock(RangingSession.Callback.class); 468 IUwbAdapter adapter = mock(IUwbAdapter.class); 469 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 470 471 when(adapter.queryMaxDataSizeBytes(handle)).thenReturn(MAX_DATA_SIZE); 472 473 session.onRangingStarted(PARAMS); 474 assertThat(session.queryMaxDataSizeBytes()).isEqualTo(MAX_DATA_SIZE); 475 } 476 477 @Test testOnRangingResult_OnReportReceivedCalledWhenOpen()478 public void testOnRangingResult_OnReportReceivedCalledWhenOpen() { 479 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 480 RangingSession.Callback callback = mock(RangingSession.Callback.class); 481 IUwbAdapter adapter = mock(IUwbAdapter.class); 482 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 483 484 assertFalse(session.isOpen()); 485 session.onRangingStarted(PARAMS); 486 assertTrue(session.isOpen()); 487 488 // Verify that the onReportReceived callback was invoked 489 RangingReport report = UwbTestUtils.getRangingReports(1); 490 session.onRangingResult(report); 491 verify(callback, times(1)).onReportReceived(report); 492 } 493 494 @Test testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen()495 public void testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen() { 496 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 497 RangingSession.Callback callback = mock(RangingSession.Callback.class); 498 IUwbAdapter adapter = mock(IUwbAdapter.class); 499 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 500 501 assertFalse(session.isOpen()); 502 503 // Verify that the onReportReceived callback was invoked 504 RangingReport report = UwbTestUtils.getRangingReports(1); 505 session.onRangingResult(report); 506 verify(callback, times(0)).onReportReceived(report); 507 } 508 509 @Test testOnRangingRoundsUpdateDtTag()510 public void testOnRangingRoundsUpdateDtTag() throws RemoteException { 511 assumeTrue(SdkLevel.isAtLeastU()); // Test should only run on U+ devices. 512 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 513 RangingSession.Callback callback = mock(RangingSession.Callback.class); 514 IUwbAdapter adapter = mock(IUwbAdapter.class); 515 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 516 PersistableBundle params = new PersistableBundle(); 517 assertFalse(session.isOpen()); 518 519 session.onRangingOpened(); 520 session.onRangingStarted(params); 521 session.updateRangingRoundsDtTag(params); 522 523 verify(adapter, times(1)).updateRangingRoundsDtTag(handle, params); 524 } 525 526 @Test testOnRangingRoundsUpdateDtTagStatus()527 public void testOnRangingRoundsUpdateDtTagStatus() { 528 assumeTrue(SdkLevel.isAtLeastU()); // Test should only run on U+ devices. 529 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 530 RangingSession.Callback callback = mock(RangingSession.Callback.class); 531 IUwbAdapter adapter = mock(IUwbAdapter.class); 532 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 533 PersistableBundle params = new PersistableBundle(); 534 assertFalse(session.isOpen()); 535 536 session.onRangingOpened(); 537 session.onRangingRoundsUpdateDtTagStatus(params); 538 539 verify(callback, times(1)).onRangingRoundsUpdateDtTagStatus(params); 540 } 541 542 @Test testQueryMaxDataSizeBytes()543 public void testQueryMaxDataSizeBytes() throws RemoteException { 544 assumeTrue(SdkLevel.isAtLeastU()); // Test should only run on U+ devices. 545 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 546 RangingSession.Callback callback = mock(RangingSession.Callback.class); 547 IUwbAdapter adapter = mock(IUwbAdapter.class); 548 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 549 550 when(adapter.queryMaxDataSizeBytes(handle)).thenReturn(MAX_DATA_SIZE); 551 552 // Confirm that queryMaxDataSizeBytes() throws an IllegalStateException when the ranging 553 // session is not open. 554 assertFalse(session.isOpen()); 555 verifyThrowIllegalState(() -> session.queryMaxDataSizeBytes()); 556 557 // Confirm that queryMaxDataSizeBytes() returns a value when the ranging session has been 558 // opened. 559 session.onRangingOpened(); 560 assertEquals(session.queryMaxDataSizeBytes(), MAX_DATA_SIZE); 561 562 // Confirm that queryMaxDataSizeBytes() returns a value when the ranging session has been 563 // started. 564 session.onRangingStarted(PARAMS); 565 assertEquals(session.queryMaxDataSizeBytes(), MAX_DATA_SIZE); 566 567 // Confirm that queryMaxDataSizeBytes() still returns a value, when the ranging session 568 // was stopped. 569 session.onRangingStopped(REASON, PARAMS); 570 assertEquals(session.queryMaxDataSizeBytes(), MAX_DATA_SIZE); 571 572 // Confirm that queryMaxDataSizeBytes() throws an IllegalStateException when the ranging 573 // session has now been closed. 574 session.onRangingClosed(REASON, PARAMS); 575 verifyThrowIllegalState(() -> session.queryMaxDataSizeBytes()); 576 } 577 578 @Test testSetHybridSessionControllerConfiguration_NotOpenSession_ThrowsException()579 public void testSetHybridSessionControllerConfiguration_NotOpenSession_ThrowsException() 580 throws RemoteException { 581 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 582 // Mocking necessary objects and behaviors 583 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 584 RangingSession.Callback callback = mock(RangingSession.Callback.class); 585 IUwbAdapter adapter = mock(IUwbAdapter.class); 586 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 587 sessionHandle); 588 assertFalse(rangingSession.isOpen()); 589 590 // Verify that an IllegalStateException is thrown when attempting to set the hybrid session 591 // controller configuration while the session is not open. 592 verifyThrowIllegalState(() -> 593 rangingSession.setHybridSessionControllerConfiguration(PARAMS)); 594 } 595 596 @Test testSetHybridSessionControllerConfiguration_OpenSession_Success()597 public void testSetHybridSessionControllerConfiguration_OpenSession_Success() 598 throws RemoteException { 599 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 600 // Mocking necessary objects and behaviors 601 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 602 RangingSession.Callback callback = mock(RangingSession.Callback.class); 603 IUwbAdapter adapter = mock(IUwbAdapter.class); 604 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 605 sessionHandle); 606 rangingSession.onRangingOpened(); 607 608 // Invoke the method being tested 609 rangingSession.setHybridSessionControllerConfiguration(PARAMS); 610 611 // Verify that the adapter's method setHybridSessionControllerConfiguration() is called once 612 // with the correct parameters. 613 verify(adapter).setHybridSessionControllerConfiguration(sessionHandle, PARAMS); 614 615 // Simulate the session being closed 616 rangingSession.onRangingClosed(REASON, PARAMS); 617 618 // Verify that an IllegalStateException is thrown when attempting to set the configuration 619 // after the session is closed. 620 verifyThrowIllegalState(() -> 621 rangingSession.setHybridSessionControllerConfiguration(PARAMS)); 622 } 623 624 @Test testOnHybridSessionControllerConfigured_WhenSessionOpened_CallbackMethodCalled()625 public void testOnHybridSessionControllerConfigured_WhenSessionOpened_CallbackMethodCalled() 626 throws RemoteException { 627 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 628 // Mocking necessary objects and behaviors 629 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 630 RangingSession.Callback callback = mock(RangingSession.Callback.class); 631 IUwbAdapter adapter = mock(IUwbAdapter.class); 632 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 633 sessionHandle); 634 635 // Simulate the session opening 636 rangingSession.onRangingOpened(); 637 rangingSession.onHybridSessionControllerConfigured(PARAMS); 638 639 // Verify that the callback method onHybridSessionControllerConfigured() is called once 640 // with the correct parameters. 641 verify(callback).onHybridSessionControllerConfigured(PARAMS); 642 } 643 644 @Test 645 public void testOnHybridSessionControllerConfigurationFailed_WhenSessionOpenedCallbackCalled()646 testOnHybridSessionControllerConfigurationFailed_WhenSessionOpenedCallbackCalled() 647 throws RemoteException { 648 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 649 // Mocking necessary objects and behaviors 650 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 651 RangingSession.Callback callback = mock(RangingSession.Callback.class); 652 IUwbAdapter adapter = mock(IUwbAdapter.class); 653 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 654 sessionHandle); 655 656 // Simulate the session opening 657 rangingSession.onRangingOpened(); 658 rangingSession.onHybridSessionControllerConfigurationFailed(REASON, PARAMS); 659 660 // Verify that the callback method onHybridSessionControllerConfigurationFailed() is 661 // called once with the correct parameters. 662 verify(callback).onHybridSessionControllerConfigurationFailed(REASON, PARAMS); 663 } 664 665 @Test testSetHybridSessionControleeConfiguration_WhenSessionNotOpen_ThrowsException()666 public void testSetHybridSessionControleeConfiguration_WhenSessionNotOpen_ThrowsException() 667 throws RemoteException { 668 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 669 // Mocking necessary objects and behaviors 670 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 671 RangingSession.Callback callback = mock(RangingSession.Callback.class); 672 IUwbAdapter adapter = mock(IUwbAdapter.class); 673 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 674 sessionHandle); 675 assertFalse(rangingSession.isOpen()); 676 677 // Verify that an IllegalStateException is thrown when attempting to set the hybrid session 678 // controlee configuration while the session is not open. 679 verifyThrowIllegalState(() -> rangingSession.setHybridSessionControleeConfiguration( 680 PARAMS)); 681 } 682 683 @Test testSetHybridSessionControleeConfiguration_OpenSession_Success()684 public void testSetHybridSessionControleeConfiguration_OpenSession_Success() 685 throws RemoteException { 686 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 687 // Mocking necessary objects and behaviors 688 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 689 RangingSession.Callback callback = mock(RangingSession.Callback.class); 690 IUwbAdapter adapter = mock(IUwbAdapter.class); 691 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 692 sessionHandle); 693 rangingSession.onRangingOpened(); 694 695 // Invoke the method being tested 696 rangingSession.setHybridSessionControleeConfiguration(PARAMS); 697 698 // Verify that the adapter's method setHybridSessionControleeConfiguration() is called once 699 // with the correct parameters. 700 verify(adapter).setHybridSessionControleeConfiguration(sessionHandle, PARAMS); 701 702 // Simulate the session being closed 703 rangingSession.onRangingClosed(REASON, PARAMS); 704 705 // Verify that an IllegalStateException is thrown when attempting to set the configuration 706 // after the session is closed. 707 verifyThrowIllegalState(() -> 708 rangingSession.setHybridSessionControleeConfiguration(PARAMS)); 709 } 710 711 @Test testOnHybridSessionControleeConfigured_WhenSessionOpened_CallbackMethodCalled()712 public void testOnHybridSessionControleeConfigured_WhenSessionOpened_CallbackMethodCalled() 713 throws RemoteException { 714 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 715 // Mocking necessary objects and behaviors 716 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 717 RangingSession.Callback callback = mock(RangingSession.Callback.class); 718 IUwbAdapter adapter = mock(IUwbAdapter.class); 719 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 720 sessionHandle); 721 722 // Simulate the session opening 723 rangingSession.onRangingOpened(); 724 rangingSession.onHybridSessionControleeConfigured(PARAMS); 725 726 // Verify that the callback method onHybridSessionControleeConfigured() is called once 727 // with the correct parameters. 728 verify(callback).onHybridSessionControleeConfigured(PARAMS); 729 } 730 731 @Test 732 public void testOnHybridSessionControleeConfigurationFailed_WhenSessionOpenedCallbackCalled()733 testOnHybridSessionControleeConfigurationFailed_WhenSessionOpenedCallbackCalled() 734 throws RemoteException { 735 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 736 // Mocking necessary objects and behaviors 737 SessionHandle sessionHandle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 738 RangingSession.Callback callback = mock(RangingSession.Callback.class); 739 IUwbAdapter adapter = mock(IUwbAdapter.class); 740 RangingSession rangingSession = new RangingSession(EXECUTOR, callback, adapter, 741 sessionHandle); 742 743 // Simulate the session opening 744 rangingSession.onRangingOpened(); 745 rangingSession.onHybridSessionControleeConfigurationFailed(REASON, PARAMS); 746 747 // Verify that the callback method onHybridSessionControleeConfigurationFailed() is 748 // called once with the correct parameters. 749 verify(callback).onHybridSessionControleeConfigurationFailed(REASON, PARAMS); 750 } 751 752 @Test testSetDataTransferPhaseConfig()753 public void testSetDataTransferPhaseConfig() throws RemoteException { 754 assumeTrue(SdkLevel.isAtLeastV()); // Test should only run on V+ devices. 755 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 756 RangingSession.Callback callback = mock(RangingSession.Callback.class); 757 IUwbAdapter adapter = mock(IUwbAdapter.class); 758 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 759 760 // Confirm that setDataTransferPhaseConfig() throws an IllegalStateException 761 // when the ranging session is not open. 762 assertFalse(session.isOpen()); 763 verifyThrowIllegalState(() -> session.setDataTransferPhaseConfig(PARAMS)); 764 765 // Confirm that setDataTransferPhaseConfig() returns a value when the ranging 766 // session has been opened. 767 session.onRangingOpened(); 768 verifyNoThrowIllegalState(() -> session.setDataTransferPhaseConfig(PARAMS)); 769 770 // Confirm that setDataTransferPhaseConfig() throws an IllegalStateException when the 771 // ranging session has now been closed. 772 session.onRangingClosed(REASON, PARAMS); 773 verifyThrowIllegalState(() -> session.setDataTransferPhaseConfig(PARAMS)); 774 } 775 776 @Test testPoseUpdate()777 public void testPoseUpdate() throws RemoteException { 778 assumeTrue(SdkLevel.isAtLeastU()); // Test should only run on U+ devices. 779 SessionHandle handle = new SessionHandle(HANDLE_ID, ATTRIBUTION_SOURCE, PID); 780 RangingSession.Callback callback = mock(RangingSession.Callback.class); 781 IUwbAdapter adapter = mock(IUwbAdapter.Stub.class); 782 doNothing().when(adapter).updatePose(any(), any()); 783 RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle); 784 assertFalse(session.isOpen()); 785 786 session.onRangingOpened(); 787 session.updatePose(PARAMS); 788 789 ArgumentCaptor<SessionHandle> shCaptor = ArgumentCaptor.forClass(SessionHandle.class); 790 ArgumentCaptor<PersistableBundle> bundleCaptor = ArgumentCaptor.forClass( 791 PersistableBundle.class); 792 793 verify(adapter, times(1)) 794 .updatePose(shCaptor.capture(), bundleCaptor.capture()); 795 assertEquals(handle.getId(), shCaptor.getValue().getId()); 796 } 797 verifyOpenState(RangingSession session, boolean expected)798 private void verifyOpenState(RangingSession session, boolean expected) { 799 assertEquals(expected, session.isOpen()); 800 } 801 verifyThrowIllegalState(Runnable runnable)802 private void verifyThrowIllegalState(Runnable runnable) { 803 try { 804 runnable.run(); 805 fail(); 806 } catch (IllegalStateException e) { 807 // Pass 808 } 809 } 810 verifyNoThrowIllegalState(Runnable runnable)811 private void verifyNoThrowIllegalState(Runnable runnable) { 812 try { 813 runnable.run(); 814 } catch (IllegalStateException e) { 815 fail(); 816 } 817 } 818 819 abstract class AdapterAnswer implements Answer { 820 protected RangingSession mSession; 821 AdapterAnswer(RangingSession session)822 protected AdapterAnswer(RangingSession session) { 823 mSession = session; 824 } 825 } 826 827 class OpenAnswer extends AdapterAnswer { OpenAnswer(RangingSession session)828 OpenAnswer(RangingSession session) { 829 super(session); 830 } 831 832 @Override answer(InvocationOnMock invocation)833 public Object answer(InvocationOnMock invocation) { 834 PersistableBundle argParams = invocation.getArgument(1); 835 if (argParams != null) { 836 mSession.onRangingOpened(); 837 } else { 838 mSession.onRangingOpenFailed(REASON_BAD_PARAMETERS, PARAMS); 839 } 840 return null; 841 } 842 } 843 844 class StartAnswer extends AdapterAnswer { StartAnswer(RangingSession session)845 StartAnswer(RangingSession session) { 846 super(session); 847 } 848 849 @Override answer(InvocationOnMock invocation)850 public Object answer(InvocationOnMock invocation) { 851 PersistableBundle argParams = invocation.getArgument(1); 852 if (argParams != null) { 853 mSession.onRangingStarted(PARAMS); 854 } else { 855 mSession.onRangingStartFailed(REASON_BAD_PARAMETERS, PARAMS); 856 } 857 return null; 858 } 859 } 860 861 class ReconfigureAnswer extends AdapterAnswer { ReconfigureAnswer(RangingSession session)862 ReconfigureAnswer(RangingSession session) { 863 super(session); 864 } 865 866 @Override answer(InvocationOnMock invocation)867 public Object answer(InvocationOnMock invocation) { 868 PersistableBundle argParams = invocation.getArgument(1); 869 if (argParams != null) { 870 mSession.onRangingReconfigured(PARAMS); 871 } else { 872 mSession.onRangingReconfigureFailed(REASON_BAD_PARAMETERS, PARAMS); 873 } 874 return null; 875 } 876 } 877 878 class PauseAnswer extends AdapterAnswer { PauseAnswer(RangingSession session)879 PauseAnswer(RangingSession session) { 880 super(session); 881 } 882 883 @Override answer(InvocationOnMock invocation)884 public Object answer(InvocationOnMock invocation) { 885 PersistableBundle argParams = invocation.getArgument(1); 886 if (argParams != null) { 887 mSession.onRangingPaused(PARAMS); 888 } else { 889 mSession.onRangingPauseFailed(REASON_BAD_PARAMETERS, PARAMS); 890 } 891 return null; 892 } 893 } 894 895 class ResumeAnswer extends AdapterAnswer { ResumeAnswer(RangingSession session)896 ResumeAnswer(RangingSession session) { 897 super(session); 898 } 899 900 @Override answer(InvocationOnMock invocation)901 public Object answer(InvocationOnMock invocation) { 902 PersistableBundle argParams = invocation.getArgument(1); 903 if (argParams != null) { 904 mSession.onRangingResumed(PARAMS); 905 } else { 906 mSession.onRangingResumeFailed(REASON_BAD_PARAMETERS, PARAMS); 907 } 908 return null; 909 } 910 } 911 912 class ControleeAddAnswer extends AdapterAnswer { ControleeAddAnswer(RangingSession session)913 ControleeAddAnswer(RangingSession session) { 914 super(session); 915 } 916 917 @Override answer(InvocationOnMock invocation)918 public Object answer(InvocationOnMock invocation) { 919 PersistableBundle argParams = invocation.getArgument(1); 920 if (argParams != null) { 921 mSession.onControleeAdded(PARAMS); 922 } else { 923 mSession.onControleeAddFailed(REASON_BAD_PARAMETERS, PARAMS); 924 } 925 return null; 926 } 927 } 928 929 class ControleeRemoveAnswer extends AdapterAnswer { ControleeRemoveAnswer(RangingSession session)930 ControleeRemoveAnswer(RangingSession session) { 931 super(session); 932 } 933 934 @Override answer(InvocationOnMock invocation)935 public Object answer(InvocationOnMock invocation) { 936 PersistableBundle argParams = invocation.getArgument(1); 937 if (argParams != null) { 938 mSession.onControleeRemoved(PARAMS); 939 } else { 940 mSession.onControleeRemoveFailed(REASON_BAD_PARAMETERS, PARAMS); 941 } 942 return null; 943 } 944 } 945 946 class DataSendAnswer extends AdapterAnswer { DataSendAnswer(RangingSession session)947 DataSendAnswer(RangingSession session) { 948 super(session); 949 } 950 951 @Override answer(InvocationOnMock invocation)952 public Object answer(InvocationOnMock invocation) { 953 UwbAddress argParams = invocation.getArgument(1); 954 if (argParams != null) { 955 mSession.onDataSent(UWB_ADDRESS, PARAMS); 956 } else { 957 mSession.onDataSendFailed(null, REASON_BAD_PARAMETERS, PARAMS); 958 } 959 return null; 960 } 961 } 962 963 class StopAnswer extends AdapterAnswer { StopAnswer(RangingSession session)964 StopAnswer(RangingSession session) { 965 super(session); 966 } 967 968 @Override answer(InvocationOnMock invocation)969 public Object answer(InvocationOnMock invocation) { 970 mSession.onRangingStopped(REASON, PARAMS); 971 return null; 972 } 973 } 974 975 class CloseAnswer extends AdapterAnswer { CloseAnswer(RangingSession session)976 CloseAnswer(RangingSession session) { 977 super(session); 978 } 979 980 @Override answer(InvocationOnMock invocation)981 public Object answer(InvocationOnMock invocation) { 982 mSession.onRangingClosed(REASON, PARAMS); 983 return null; 984 } 985 } 986 987 class DataTransferPhaseConfigAnswer extends AdapterAnswer { DataTransferPhaseConfigAnswer(RangingSession session)988 DataTransferPhaseConfigAnswer(RangingSession session) { 989 super(session); 990 } 991 992 @Override answer(InvocationOnMock invocation)993 public Object answer(InvocationOnMock invocation) { 994 PersistableBundle argParams = invocation.getArgument(1); 995 System.out.println("AKJ: DataTransferPhaseConfigAnswer: argParams = " + argParams); 996 if (argParams != null) { 997 mSession.onDataTransferPhaseConfigured(PARAMS); 998 } else { 999 mSession.onDataTransferPhaseConfigFailed(REASON_BAD_PARAMETERS, null); 1000 } 1001 return null; 1002 } 1003 } 1004 1005 class HybridSessionControllerConfigurationAnswer extends AdapterAnswer { HybridSessionControllerConfigurationAnswer(RangingSession session)1006 HybridSessionControllerConfigurationAnswer(RangingSession session) { 1007 super(session); 1008 } 1009 1010 @Override answer(InvocationOnMock invocation)1011 public Object answer(InvocationOnMock invocation) { 1012 PersistableBundle argParams = invocation.getArgument(1); 1013 if (argParams != null) { 1014 mSession.onHybridSessionControllerConfigured(PARAMS); 1015 } else { 1016 mSession.onHybridSessionControllerConfigurationFailed(REASON_BAD_PARAMETERS, null); 1017 } 1018 return null; 1019 } 1020 } 1021 1022 class HybridSessionControleeConfigurationAnswer extends AdapterAnswer { HybridSessionControleeConfigurationAnswer(RangingSession session)1023 HybridSessionControleeConfigurationAnswer(RangingSession session) { 1024 super(session); 1025 } 1026 1027 @Override answer(InvocationOnMock invocation)1028 public Object answer(InvocationOnMock invocation) { 1029 PersistableBundle argParams = invocation.getArgument(1); 1030 if (argParams != null) { 1031 mSession.onHybridSessionControleeConfigured(PARAMS); 1032 } else { 1033 mSession.onHybridSessionControleeConfigurationFailed(REASON_BAD_PARAMETERS, null); 1034 } 1035 return null; 1036 } 1037 } 1038 } 1039