1 /* 2 * Copyright 2020 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 android.Manifest; 20 import android.annotation.FlaggedApi; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.os.Binder; 26 import android.os.Build; 27 import android.os.PersistableBundle; 28 import android.os.RemoteException; 29 import android.util.Log; 30 31 import androidx.annotation.RequiresApi; 32 33 import com.android.modules.utils.build.SdkLevel; 34 35 import java.lang.annotation.Retention; 36 import java.lang.annotation.RetentionPolicy; 37 import java.util.concurrent.Executor; 38 39 /** 40 * This class provides a way to control an active UWB ranging session. 41 * <p>It also defines the required {@link RangingSession.Callback} that must be implemented 42 * in order to be notified of UWB ranging results and status events related to the 43 * {@link RangingSession}. 44 * 45 * <p>To get an instance of {@link RangingSession}, first use 46 * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} to request to open a 47 * session. Once the session is opened, a {@link RangingSession} object is provided through 48 * {@link RangingSession.Callback#onOpened(RangingSession)}. If opening a session fails, the failure 49 * is reported through {@link RangingSession.Callback#onOpenFailed(int, PersistableBundle)} with the 50 * failure reason. 51 * 52 * @hide 53 */ 54 @SystemApi 55 public final class RangingSession implements AutoCloseable { 56 private final String mTag = "Uwb.RangingSession[" + this + "]"; 57 private final SessionHandle mSessionHandle; 58 private final IUwbAdapter mAdapter; 59 private final Executor mExecutor; 60 private final Callback mCallback; 61 private final String mChipId; 62 63 private enum State { 64 /** 65 * The state of the {@link RangingSession} until 66 * {@link RangingSession.Callback#onOpened(RangingSession)} is invoked 67 */ 68 INIT, 69 70 /** 71 * The {@link RangingSession} is initialized and ready to begin ranging 72 */ 73 IDLE, 74 75 /** 76 * The {@link RangingSession} is actively ranging 77 */ 78 ACTIVE, 79 80 /** 81 * The {@link RangingSession} is closed and may not be used for ranging. 82 */ 83 CLOSED 84 } 85 86 private State mState = State.INIT; 87 88 /** 89 * Interface for receiving {@link RangingSession} events 90 */ 91 public interface Callback { 92 /** 93 * @hide 94 */ 95 @Retention(RetentionPolicy.SOURCE) 96 @IntDef(value = { 97 REASON_UNKNOWN, 98 REASON_LOCAL_REQUEST, 99 REASON_REMOTE_REQUEST, 100 REASON_BAD_PARAMETERS, 101 REASON_GENERIC_ERROR, 102 REASON_MAX_SESSIONS_REACHED, 103 REASON_SYSTEM_POLICY, 104 REASON_PROTOCOL_SPECIFIC_ERROR, 105 REASON_MAX_RR_RETRY_REACHED, 106 REASON_SERVICE_DISCOVERY_FAILURE, 107 REASON_SERVICE_CONNECTION_FAILURE, 108 REASON_SE_NOT_SUPPORTED, 109 REASON_SE_INTERACTION_FAILURE, 110 REASON_INSUFFICIENT_SLOTS_PER_RR, 111 REASON_SYSTEM_REGULATION, 112 REASON_INBAND_SESSION_STOP, 113 }) 114 @interface Reason {} 115 116 /** 117 * Indicates that the session was closed or failed to open due to an unknown reason 118 */ 119 int REASON_UNKNOWN = 0; 120 121 /** 122 * Indicates that the session was closed or failed to open because 123 * {@link AutoCloseable#close()} or {@link RangingSession#close()} was called 124 */ 125 int REASON_LOCAL_REQUEST = 1; 126 127 /** 128 * Indicates that the session was closed or failed to open due to an explicit request from 129 * the remote device. 130 */ 131 int REASON_REMOTE_REQUEST = 2; 132 133 /** 134 * Indicates that the session was closed or failed to open due to erroneous parameters 135 */ 136 int REASON_BAD_PARAMETERS = 3; 137 138 /** 139 * Indicates an error on this device besides the error code already listed 140 */ 141 int REASON_GENERIC_ERROR = 4; 142 143 /** 144 * Indicates that the number of currently open sessions supported by the device and 145 * additional sessions may not be opened. 146 */ 147 int REASON_MAX_SESSIONS_REACHED = 5; 148 149 /** 150 * Indicates that the local system policy caused the change, such 151 * as privacy policy, power management policy, permissions, and more. 152 */ 153 int REASON_SYSTEM_POLICY = 6; 154 155 /** 156 * Indicates a protocol specific error. The associated {@link PersistableBundle} should be 157 * consulted for additional information. 158 */ 159 int REASON_PROTOCOL_SPECIFIC_ERROR = 7; 160 161 /** 162 * Indicates that the max number of retry attempts for a ranging attempt has been reached. 163 */ 164 int REASON_MAX_RR_RETRY_REACHED = 9; 165 166 /** 167 * Indicates a failure to discover the service after activation. 168 */ 169 int REASON_SERVICE_DISCOVERY_FAILURE = 10; 170 171 /** 172 * Indicates a failure to connect to the service after discovery. 173 */ 174 int REASON_SERVICE_CONNECTION_FAILURE = 11; 175 176 /** 177 * The device doesn’t support FiRA Applet. 178 */ 179 int REASON_SE_NOT_SUPPORTED = 12; 180 181 /** 182 * SE interactions failed. 183 */ 184 int REASON_SE_INTERACTION_FAILURE = 13; 185 186 /** 187 * Indicate insufficient slots per ranging round. 188 */ 189 int REASON_INSUFFICIENT_SLOTS_PER_RR = 14; 190 191 /** 192 * Indicate that a system regulation caused the change, such as no allowed UWB channels in 193 * the country. 194 */ 195 int REASON_SYSTEM_REGULATION = 15; 196 197 /** 198 * Indicates session was stopped due to inband signal. 199 */ 200 @FlaggedApi("com.android.uwb.flags.reason_inband_session_stop") 201 int REASON_INBAND_SESSION_STOP = 16; 202 203 /** 204 * @hide 205 */ 206 @Retention(RetentionPolicy.SOURCE) 207 @IntDef(value = { 208 CONTROLEE_FAILURE_REASON_MAX_CONTROLEE_REACHED, 209 }) 210 @interface ControleeFailureReason {} 211 212 /** 213 * Indicates that the session has reached the max number of controlees supported by the 214 * device. This is applicable to only one to many sessions and sent in response to a 215 * request to add a new controlee to an ongoing session. 216 */ 217 int CONTROLEE_FAILURE_REASON_MAX_CONTROLEE_REACHED = 0; 218 219 /** 220 * @hide 221 */ 222 @Retention(RetentionPolicy.SOURCE) 223 @IntDef(value = { 224 DATA_FAILURE_REASON_DATA_SIZE_TOO_LARGE, 225 }) 226 @interface DataFailureReason {} 227 228 /** 229 * Indicates that the size of the data being sent or received is too large. 230 */ 231 int DATA_FAILURE_REASON_DATA_SIZE_TOO_LARGE = 10; 232 233 /** 234 * Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} 235 * is successful 236 * 237 * @param session the newly opened {@link RangingSession} 238 */ onOpened(@onNull RangingSession session)239 void onOpened(@NonNull RangingSession session); 240 241 /** 242 * Invoked if {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}} 243 * fails 244 * 245 * @param reason the failure reason 246 * @param params protocol specific parameters 247 */ onOpenFailed(@eason int reason, @NonNull PersistableBundle params)248 void onOpenFailed(@Reason int reason, @NonNull PersistableBundle params); 249 250 /** 251 * Invoked either, 252 * - when {@link RangingSession#start(PersistableBundle)} is successful if the session is 253 * using a custom profile, OR 254 * - when platform starts ranging after OOB discovery + negotiation if the session is 255 * using a platform defined profile. 256 * @param sessionInfo session specific parameters from the lower layers 257 */ onStarted(@onNull PersistableBundle sessionInfo)258 void onStarted(@NonNull PersistableBundle sessionInfo); 259 260 /** 261 * Invoked either, 262 * - when {@link RangingSession#start(PersistableBundle)} fails if 263 * the session is using a custom profile, OR 264 * - when platform fails ranging after OOB discovery + negotiation if the 265 * session is using a platform defined profile. 266 * 267 * @param reason the failure reason 268 * @param params protocol specific parameters 269 */ onStartFailed(@eason int reason, @NonNull PersistableBundle params)270 void onStartFailed(@Reason int reason, @NonNull PersistableBundle params); 271 272 /** 273 * Invoked when a request to reconfigure the session succeeds 274 * 275 * @param params the updated ranging configuration 276 */ onReconfigured(@onNull PersistableBundle params)277 void onReconfigured(@NonNull PersistableBundle params); 278 279 /** 280 * Invoked when a request to reconfigure the session fails 281 * 282 * @param reason reason the session failed to be reconfigured 283 * @param params protocol specific failure reasons 284 */ onReconfigureFailed(@eason int reason, @NonNull PersistableBundle params)285 void onReconfigureFailed(@Reason int reason, @NonNull PersistableBundle params); 286 287 /** 288 * Invoked when a request to stop the session succeeds 289 * 290 * @param reason reason for the session stop 291 * @param parameters protocol specific parameters related to the stop reason 292 */ onStopped(@eason int reason, @NonNull PersistableBundle parameters)293 void onStopped(@Reason int reason, @NonNull PersistableBundle parameters); 294 295 /** 296 * Invoked when a request to stop the session fails 297 * 298 * @param reason reason the session failed to be stopped 299 * @param params protocol specific failure reasons 300 */ onStopFailed(@eason int reason, @NonNull PersistableBundle params)301 void onStopFailed(@Reason int reason, @NonNull PersistableBundle params); 302 303 /** 304 * Invoked when session is either closed spontaneously, or per user request via 305 * {@link RangingSession#close()} or {@link AutoCloseable#close()}. 306 * 307 * @param reason reason for the session closure 308 * @param parameters protocol specific parameters related to the close reason 309 */ onClosed(@eason int reason, @NonNull PersistableBundle parameters)310 void onClosed(@Reason int reason, @NonNull PersistableBundle parameters); 311 312 /** 313 * Called once per ranging interval even when a ranging measurement fails 314 * 315 * @param rangingReport ranging report for this interval's measurements 316 */ onReportReceived(@onNull RangingReport rangingReport)317 void onReportReceived(@NonNull RangingReport rangingReport); 318 319 /** 320 * Invoked when a new controlee is added to an ongoing one-to many session. 321 * 322 * @param parameters protocol specific parameters for the new controlee 323 */ onControleeAdded(@onNull PersistableBundle parameters)324 default void onControleeAdded(@NonNull PersistableBundle parameters) {} 325 326 /** 327 * Invoked when a new controlee is added to an ongoing one-to many session. 328 * 329 * @param reason reason for the controlee add failure 330 * @param parameters protocol specific parameters related to the failure 331 */ onControleeAddFailed( @ontroleeFailureReason int reason, @NonNull PersistableBundle parameters)332 default void onControleeAddFailed( 333 @ControleeFailureReason int reason, @NonNull PersistableBundle parameters) {} 334 335 /** 336 * Invoked when an existing controlee is removed from an ongoing one-to many session. 337 * 338 * @param parameters protocol specific parameters for the existing controlee 339 */ onControleeRemoved(@onNull PersistableBundle parameters)340 default void onControleeRemoved(@NonNull PersistableBundle parameters) {} 341 342 /** 343 * Invoked when a new controlee is added to an ongoing one-to many session. 344 * 345 * @param reason reason for the controlee remove failure 346 * @param parameters protocol specific parameters related to the failure 347 */ onControleeRemoveFailed( @ontroleeFailureReason int reason, @NonNull PersistableBundle parameters)348 default void onControleeRemoveFailed( 349 @ControleeFailureReason int reason, @NonNull PersistableBundle parameters) {} 350 351 /** 352 * Invoked when an ongoing session is successfully pauseed. 353 * 354 * @param parameters protocol specific parameters sent for suspension 355 */ onPaused(@onNull PersistableBundle parameters)356 default void onPaused(@NonNull PersistableBundle parameters) {} 357 358 /** 359 * Invoked when an ongoing session suspension fails. 360 * 361 * @param reason reason for the suspension failure 362 * @param parameters protocol specific parameters for suspension failure 363 */ onPauseFailed(@eason int reason, @NonNull PersistableBundle parameters)364 default void onPauseFailed(@Reason int reason, @NonNull PersistableBundle parameters) {} 365 366 /** 367 * Invoked when a pauseed session is successfully resumed. 368 * 369 * @param parameters protocol specific parameters sent for suspension 370 */ onResumed(@onNull PersistableBundle parameters)371 default void onResumed(@NonNull PersistableBundle parameters) {} 372 373 /** 374 * Invoked when a pauseed session resumption fails. 375 * 376 * @param reason reason for the resumption failure 377 * @param parameters protocol specific parameters for resumption failure 378 */ onResumeFailed(@eason int reason, @NonNull PersistableBundle parameters)379 default void onResumeFailed(@Reason int reason, @NonNull PersistableBundle parameters) {} 380 381 /** 382 * Invoked when data is successfully sent via {@link RangingSession#sendData(UwbAddress, 383 * PersistableBundle, byte[])}. 384 * 385 * @param remoteDeviceAddress remote device's address 386 * @param parameters protocol specific parameters sent for suspension 387 */ onDataSent(@onNull UwbAddress remoteDeviceAddress, @NonNull PersistableBundle parameters)388 default void onDataSent(@NonNull UwbAddress remoteDeviceAddress, 389 @NonNull PersistableBundle parameters) {} 390 391 /** 392 * Invoked when data send to a remote device via {@link RangingSession#sendData(UwbAddress, 393 * PersistableBundle, byte[])} fails. 394 * 395 * @param remoteDeviceAddress remote device's address 396 * @param reason reason for the resumption failure 397 * @param parameters protocol specific parameters for resumption failure 398 */ onDataSendFailed(@onNull UwbAddress remoteDeviceAddress, @DataFailureReason int reason, @NonNull PersistableBundle parameters)399 default void onDataSendFailed(@NonNull UwbAddress remoteDeviceAddress, 400 @DataFailureReason int reason, @NonNull PersistableBundle parameters) {} 401 402 /** 403 * Invoked when data is received successfully from a remote device. 404 * The data is received piggybacked over RRM (initiator -> responder) or 405 * RIM (responder -> initiator). 406 * <p> This is only functional on a FIRA 2.0 compliant device. 407 * 408 * @param remoteDeviceAddress remote device's address 409 * @param data Raw data received 410 * @param parameters protocol specific parameters for the received data 411 */ onDataReceived(@onNull UwbAddress remoteDeviceAddress, @NonNull PersistableBundle parameters, @NonNull byte[] data)412 default void onDataReceived(@NonNull UwbAddress remoteDeviceAddress, 413 @NonNull PersistableBundle parameters, @NonNull byte[] data) {} 414 415 /** 416 * Invoked when data receive from a remote device fails. 417 * 418 * @param remoteDeviceAddress remote device's address 419 * @param reason reason for the reception failure 420 * @param parameters protocol specific parameters for resumption failure 421 */ onDataReceiveFailed(@onNull UwbAddress remoteDeviceAddress, @DataFailureReason int reason, @NonNull PersistableBundle parameters)422 default void onDataReceiveFailed(@NonNull UwbAddress remoteDeviceAddress, 423 @DataFailureReason int reason, @NonNull PersistableBundle parameters) {} 424 425 /** 426 * Invoked when set data transfer phase config is called successfully 427 * 428 * @param parameters protocol specific parameters for set data transfer phase config success 429 */ 430 @FlaggedApi("com.android.uwb.flags.data_transfer_phase_config") onDataTransferPhaseConfigured(@onNull PersistableBundle parameters)431 default void onDataTransferPhaseConfigured(@NonNull PersistableBundle parameters) {} 432 433 /** 434 * Invoked when set data transfer phase config is failed 435 * 436 * @param parameters protocol specific parameters for set data transfer phase config failure 437 */ 438 @FlaggedApi("com.android.uwb.flags.data_transfer_phase_config") onDataTransferPhaseConfigFailed(@eason int reason, @NonNull PersistableBundle parameters)439 default void onDataTransferPhaseConfigFailed(@Reason int reason, 440 @NonNull PersistableBundle parameters) {} 441 442 /** 443 * Invoked when service is discovered via OOB. 444 * <p> 445 * If this a one to many session, this can be invoked multiple times to indicate different 446 * peers being discovered. 447 * </p> 448 * 449 * @param parameters protocol specific params for discovered service. 450 */ onServiceDiscovered(@onNull PersistableBundle parameters)451 default void onServiceDiscovered(@NonNull PersistableBundle parameters) {} 452 453 /** 454 * Invoked when service is connected via OOB. 455 * <p> 456 * If this a one to many session, this can be invoked multiple times to indicate different 457 * peers being connected. 458 * </p> 459 * 460 * @param parameters protocol specific params for connected service. 461 */ onServiceConnected(@onNull PersistableBundle parameters)462 default void onServiceConnected(@NonNull PersistableBundle parameters) {} 463 464 /** 465 * Invoked when a response/status is received for active ranging rounds update. 466 * 467 * @param parameters bundle of ranging rounds update status 468 */ 469 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) onRangingRoundsUpdateDtTagStatus(@onNull PersistableBundle parameters)470 default void onRangingRoundsUpdateDtTagStatus(@NonNull PersistableBundle parameters) {} 471 472 /** 473 * Invoked when hybrid session controller is successfully configured. 474 * 475 * @param parameters protocol specific parameters sent for HUS session configuration 476 */ 477 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") onHybridSessionControllerConfigured( @onNull PersistableBundle parameters)478 default void onHybridSessionControllerConfigured( 479 @NonNull PersistableBundle parameters) {} 480 481 /** 482 * Invoked when hybrid session controller configuration fails. 483 * 484 * @param parameters protocol specific parameters for configuration failure 485 */ 486 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") onHybridSessionControllerConfigurationFailed( @angingChangeReason int reason, @NonNull PersistableBundle parameters)487 default void onHybridSessionControllerConfigurationFailed( 488 @RangingChangeReason int reason, @NonNull PersistableBundle parameters) { 489 } 490 491 /** 492 * Invoked when hybrid session controlee is successfully configured. 493 * 494 * @param parameters protocol specific parameters sent for HUS session configuration 495 */ 496 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") onHybridSessionControleeConfigured( @onNull PersistableBundle parameters)497 default void onHybridSessionControleeConfigured( 498 @NonNull PersistableBundle parameters) {} 499 500 /** 501 *Invoked when hybrid session controlee configuration fails. 502 * 503 * @param parameters protocol specific parameters for configuration failure 504 */ 505 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") onHybridSessionControleeConfigurationFailed( @angingChangeReason int reason, @NonNull PersistableBundle parameters)506 default void onHybridSessionControleeConfigurationFailed( 507 @RangingChangeReason int reason, @NonNull PersistableBundle parameters) {} 508 } 509 510 /** 511 * @hide 512 */ RangingSession(Executor executor, Callback callback, IUwbAdapter adapter, SessionHandle sessionHandle)513 public RangingSession(Executor executor, Callback callback, IUwbAdapter adapter, 514 SessionHandle sessionHandle) { 515 this(executor, callback, adapter, sessionHandle, /* chipId= */ null); 516 } 517 518 /** 519 * @hide 520 */ RangingSession(Executor executor, Callback callback, IUwbAdapter adapter, SessionHandle sessionHandle, String chipId)521 public RangingSession(Executor executor, Callback callback, IUwbAdapter adapter, 522 SessionHandle sessionHandle, String chipId) { 523 mState = State.INIT; 524 mExecutor = executor; 525 mCallback = callback; 526 mAdapter = adapter; 527 mSessionHandle = sessionHandle; 528 mChipId = chipId; 529 } 530 531 /** 532 * @hide 533 */ isOpen()534 public boolean isOpen() { 535 return mState == State.IDLE || mState == State.ACTIVE; 536 } 537 538 /** 539 * If the session uses custom profile, 540 * Begins ranging for the session. 541 * <p>On successfully starting a ranging session, 542 * {@link RangingSession.Callback#onStarted(PersistableBundle)} is invoked. 543 * <p>On failure to start the session, 544 * {@link RangingSession.Callback#onStartFailed(int, PersistableBundle)} 545 * is invoked. 546 * 547 * If the session uses platform defined profile (like PACS), 548 * Begins OOB discovery for the service. Once the service is discovered, 549 * UWB session params are negotiated via OOB and a UWB session will be 550 * started. 551 * <p>On successfully discovering a service, 552 * {@link RangingSession.Callback#onServiceDiscovered(PersistableBundle)} is invoked. 553 * <p>On successfully connecting to a service, 554 * {@link RangingSession.Callback#onServiceConnected(PersistableBundle)} is invoked. 555 * <p>On successfully starting a ranging session, 556 * {@link RangingSession.Callback#onStarted(PersistableBundle)} is invoked. 557 * <p>On failure to start the session, 558 * {@link RangingSession.Callback#onStartFailed(int, PersistableBundle)} 559 * is invoked. 560 * 561 * @param params configuration parameters for starting the session 562 */ 563 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) start(@onNull PersistableBundle params)564 public void start(@NonNull PersistableBundle params) { 565 if (mState != State.IDLE) { 566 throw new IllegalStateException(); 567 } 568 569 Log.v(mTag, "start - sessionHandle: " + mSessionHandle); 570 try { 571 mAdapter.startRanging(mSessionHandle, params); 572 } catch (RemoteException e) { 573 throw e.rethrowFromSystemServer(); 574 } 575 } 576 577 /** 578 * Attempts to reconfigure the session with the given parameters 579 * <p>This call may be made when the session is open. 580 * 581 * <p>On successfully reconfiguring the session 582 * {@link RangingSession.Callback#onReconfigured(PersistableBundle)} is invoked. 583 * 584 * <p>On failure to reconfigure the session, 585 * {@link RangingSession.Callback#onReconfigureFailed(int, PersistableBundle)} is invoked. 586 * 587 * @param params the parameters to reconfigure and their new values 588 */ 589 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) reconfigure(@onNull PersistableBundle params)590 public void reconfigure(@NonNull PersistableBundle params) { 591 if (mState != State.ACTIVE && mState != State.IDLE) { 592 throw new IllegalStateException(); 593 } 594 595 Log.v(mTag, "reconfigure - sessionHandle: " + mSessionHandle); 596 try { 597 mAdapter.reconfigureRanging(mSessionHandle, params); 598 } catch (RemoteException e) { 599 throw e.rethrowFromSystemServer(); 600 } 601 } 602 603 /** 604 * Stops actively ranging 605 * 606 * <p>A session that has been stopped may be resumed by calling 607 * {@link RangingSession#start(PersistableBundle)} without the need to open a new session. 608 * 609 * <p>Stopping a {@link RangingSession} is useful when the lower layers should not discard 610 * the parameters of the session, or when a session needs to be able to be resumed quickly. 611 * 612 * <p>If the {@link RangingSession} is no longer needed, use {@link RangingSession#close()} to 613 * completely close the session and allow lower layers of the stack to perform necessarily 614 * cleanup. 615 * 616 * <p>Stopped sessions may be closed by the system at any time. In such a case, 617 * {@link RangingSession.Callback#onClosed(int, PersistableBundle)} is invoked. 618 * 619 * <p>On failure to stop the session, 620 * {@link RangingSession.Callback#onStopFailed(int, PersistableBundle)} is invoked. 621 */ 622 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) stop()623 public void stop() { 624 if (mState != State.ACTIVE) { 625 throw new IllegalStateException(); 626 } 627 628 Log.v(mTag, "stop - sessionHandle: " + mSessionHandle); 629 try { 630 mAdapter.stopRanging(mSessionHandle); 631 } catch (RemoteException e) { 632 throw e.rethrowFromSystemServer(); 633 } 634 } 635 636 /** 637 * Close the ranging session 638 * 639 * <p>After calling this function, in order resume ranging, a new {@link RangingSession} must 640 * be opened by calling 641 * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}. 642 * 643 * <p>If this session is currently ranging, it will stop and close the session. 644 * <p>If the session is in the process of being opened, it will attempt to stop the session from 645 * being opened. 646 * <p>If the session is already closed, the registered 647 * {@link Callback#onClosed(int, PersistableBundle)} callback will still be invoked. 648 * 649 * <p>{@link Callback#onClosed(int, PersistableBundle)} will be invoked using the same callback 650 * object given to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} 651 * when the {@link RangingSession} was opened. The callback will be invoked after each call to 652 * {@link #close()}, even if the {@link RangingSession} is already closed. 653 */ 654 @Override 655 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) close()656 public void close() { 657 if (mState == State.CLOSED) { 658 mExecutor.execute(() -> mCallback.onClosed( 659 Callback.REASON_LOCAL_REQUEST, new PersistableBundle())); 660 return; 661 } 662 663 Log.v(mTag, "close - sessionHandle: " + mSessionHandle); 664 try { 665 mAdapter.closeRanging(mSessionHandle); 666 } catch (RemoteException e) { 667 throw e.rethrowFromSystemServer(); 668 } 669 } 670 671 /** 672 * Add a new controlee to an ongoing session. 673 * <p>This call may be made when the session is open. 674 * 675 * <p>On successfully adding a new controlee to the session 676 * {@link RangingSession.Callback#onControleeAdded(PersistableBundle)} is invoked. 677 * 678 * <p>On failure to add a new controlee to the session, 679 * {@link RangingSession.Callback#onControleeAddFailed(int, PersistableBundle)} is invoked. 680 * 681 * @param params the parameters for the new controlee 682 */ 683 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) addControlee(@onNull PersistableBundle params)684 public void addControlee(@NonNull PersistableBundle params) { 685 if (mState != State.ACTIVE && mState != State.IDLE) { 686 throw new IllegalStateException(); 687 } 688 689 Log.v(mTag, "addControlee - sessionHandle: " + mSessionHandle); 690 try { 691 mAdapter.addControlee(mSessionHandle, params); 692 } catch (RemoteException e) { 693 throw e.rethrowFromSystemServer(); 694 } 695 } 696 697 /** 698 * Remove an existing controlee from an ongoing session. 699 * <p>This call may be made when the session is open. 700 * 701 * <p>On successfully removing an existing controlee from the session 702 * {@link RangingSession.Callback#onControleeRemoved(PersistableBundle)} is invoked. 703 * 704 * <p>On failure to remove an existing controlee from the session, 705 * {@link RangingSession.Callback#onControleeRemoveFailed(int, PersistableBundle)} is invoked. 706 * 707 * @param params the parameters for the existing controlee 708 */ 709 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) removeControlee(@onNull PersistableBundle params)710 public void removeControlee(@NonNull PersistableBundle params) { 711 if (mState != State.ACTIVE && mState != State.IDLE) { 712 throw new IllegalStateException(); 713 } 714 715 Log.v(mTag, "removeControlee - sessionHandle: " + mSessionHandle); 716 try { 717 mAdapter.removeControlee(mSessionHandle, params); 718 } catch (RemoteException e) { 719 throw e.rethrowFromSystemServer(); 720 } 721 } 722 723 /** 724 * Pauses an ongoing ranging session. 725 * 726 * <p>A session that has been pauseed may be resumed by calling 727 * {@link RangingSession#resume(PersistableBundle)} without the need to open a new session. 728 * 729 * <p>Pauseing a {@link RangingSession} is useful when the lower layers should skip a few 730 * ranging rounds for a session without stopping it. 731 * 732 * <p>If the {@link RangingSession} is no longer needed, use {@link RangingSession#stop()} or 733 * {@link RangingSession#close()} to completely close the session. 734 * 735 * <p>On successfully pausing the session, 736 * {@link RangingSession.Callback#onRangingPaused(PersistableBundle)} is invoked. 737 * 738 * <p>On failure to pause the session, 739 * {@link RangingSession.Callback#onRangingPauseFailed(int, PersistableBundle)} is invoked. 740 * 741 * @param params protocol specific parameters for pausing the session 742 */ 743 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) pause(@onNull PersistableBundle params)744 public void pause(@NonNull PersistableBundle params) { 745 if (mState != State.ACTIVE) { 746 throw new IllegalStateException(); 747 } 748 749 Log.v(mTag, "pause - sessionHandle: " + mSessionHandle); 750 try { 751 mAdapter.pause(mSessionHandle, params); 752 } catch (RemoteException e) { 753 throw e.rethrowFromSystemServer(); 754 } 755 } 756 757 /** 758 * Resumes a pauseed ranging session. 759 * 760 * <p>A session that has been previously pauseed using 761 * {@link RangingSession#pause(PersistableBundle)} can be resumed by calling 762 * {@link RangingSession#resume(PersistableBundle)}. 763 * 764 * <p>On successfully resuming the session, 765 * {@link RangingSession.Callback#onRangingResumed(PersistableBundle)} is invoked. 766 * 767 * <p>On failure to resume the session, 768 * {@link RangingSession.Callback#onRangingResumeFailed(int, PersistableBundle)} is invoked. 769 * 770 * @param params protocol specific parameters the resuming the session 771 */ 772 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) resume(@onNull PersistableBundle params)773 public void resume(@NonNull PersistableBundle params) { 774 if (mState != State.ACTIVE) { 775 throw new IllegalStateException(); 776 } 777 778 Log.v(mTag, "resume - sessionHandle: " + mSessionHandle); 779 try { 780 mAdapter.resume(mSessionHandle, params); 781 } catch (RemoteException e) { 782 throw e.rethrowFromSystemServer(); 783 } 784 } 785 786 /** 787 * Send data to a remote device which is part of this ongoing session. 788 * The data is sent by piggybacking the provided data over RRM (initiator -> responder) or 789 * RIM (responder -> initiator). 790 * <p>This is only functional on a FIRA 2.0 compliant device. 791 * 792 * <p>On successfully sending the data, 793 * {@link RangingSession.Callback#onDataSent(UwbAddress, PersistableBundle)} is invoked. 794 * 795 * <p>On failure to send the data, 796 * {@link RangingSession.Callback#onDataSendFailed(UwbAddress, int, PersistableBundle)} is 797 * invoked. 798 * 799 * @param remoteDeviceAddress remote device's address 800 * @param params protocol specific parameters the sending the data 801 * @param data Raw data to be sent 802 */ 803 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) sendData(@onNull UwbAddress remoteDeviceAddress, @NonNull PersistableBundle params, @NonNull byte[] data)804 public void sendData(@NonNull UwbAddress remoteDeviceAddress, 805 @NonNull PersistableBundle params, @NonNull byte[] data) { 806 if (mState != State.ACTIVE) { 807 throw new IllegalStateException(); 808 } 809 810 Log.v(mTag, "sendData - sessionHandle: " + mSessionHandle); 811 try { 812 mAdapter.sendData(mSessionHandle, remoteDeviceAddress, params, data); 813 } catch (RemoteException e) { 814 throw e.rethrowFromSystemServer(); 815 } 816 } 817 818 /** 819 * Set data transfer phase configuration during ranging as well as dedicated data transfer. 820 * <p>This is only functional on a FIRA 2.0 compliant device. 821 * 822 * <p>On successfully sending the data transfer phase config, 823 * {@link RangingSession.Callback#onDataTransferPhaseConfigured(PersistableBundle)} is 824 * invoked. 825 * 826 * <p>On failure to send the data transfer phase config, 827 * {@link RangingSession.Callback#onDataTransferPhaseConfigFailed(PersistableBundle)} is 828 * invoked. 829 * 830 * @param params Protocol specific data transfer phase configuration parameters 831 */ 832 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) 833 @FlaggedApi("com.android.uwb.flags.data_transfer_phase_config") setDataTransferPhaseConfig(@onNull PersistableBundle params)834 public void setDataTransferPhaseConfig(@NonNull PersistableBundle params) { 835 if (!isOpen()) { 836 throw new IllegalStateException(); 837 } 838 839 Log.v(mTag, "setDataTransferPhaseConfig - sessionHandle: " + mSessionHandle); 840 try { 841 mAdapter.setDataTransferPhaseConfig(mSessionHandle, params); 842 } catch (RemoteException e) { 843 throw e.rethrowFromSystemServer(); 844 } 845 } 846 847 /** 848 * Update active ranging rounds for DT Tag. 849 * 850 * <p> On successfully sending the command, 851 * {@link RangingSession.Callback#onRangingRoundsUpdateDtTagStatus(PersistableBundle)} 852 * is invoked. 853 * @param params Parameters to configure active ranging rounds 854 */ 855 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 856 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) updateRangingRoundsDtTag(@onNull PersistableBundle params)857 public void updateRangingRoundsDtTag(@NonNull PersistableBundle params) { 858 if (mState != State.ACTIVE && mState != State.IDLE) { 859 throw new IllegalStateException(); 860 } 861 862 Log.v(mTag, "onRangingRoundsUpdateDtTag - sessionHandle: " + mSessionHandle); 863 try { 864 mAdapter.updateRangingRoundsDtTag(mSessionHandle, params); 865 } catch (RemoteException e) { 866 throw e.rethrowFromSystemServer(); 867 } 868 } 869 870 /** 871 * Query max application data size which can be sent by UWBS in one ranging round. 872 * 873 * @throws IllegalStateException, when the ranging session is not in the appropriate state for 874 * this API to be called. 875 * @return max application data size 876 */ 877 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 878 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) queryMaxDataSizeBytes()879 public int queryMaxDataSizeBytes() { 880 if (!isOpen()) { 881 throw new IllegalStateException("Ranging session is not open"); 882 } 883 884 Log.v(mTag, "QueryMaxDataSizeBytes - sessionHandle: " + mSessionHandle); 885 try { 886 return mAdapter.queryMaxDataSizeBytes(mSessionHandle); 887 } catch (RemoteException e) { 888 throw e.rethrowFromSystemServer(); 889 } 890 } 891 892 /** 893 * Sets the Hybrid UWB Session Controller Configuration. 894 * 895 * <p>On successfully setting the hybrid controller configuration, 896 * {@link RangingSession.Callback#onHybridSessionControllerConfigured(PersistableBundle)} 897 * is invoked. 898 * 899 * <p>On failing to set the hybrid controller configuration, 900 * {@link RangingSession.Callback#onHybridSessionControllerConfigurationFailed(int, 901 * PersistableBundle)} is invoked. 902 * 903 * @param params protocol specific parameters to configure the hybrid session controller 904 * @throws RemoteException if a remote error occurred 905 */ 906 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) 907 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") setHybridSessionControllerConfiguration(@onNull PersistableBundle params)908 public void setHybridSessionControllerConfiguration(@NonNull PersistableBundle params) { 909 if (!isOpen()) { 910 throw new IllegalStateException("Ranging session is not open"); 911 } 912 913 Log.v(mTag, "setHybridSessionControllerConfiguration - sessionHandle: " + mSessionHandle); 914 try { 915 mAdapter.setHybridSessionControllerConfiguration(mSessionHandle, params); 916 } catch (RemoteException e) { 917 throw e.rethrowFromSystemServer(); 918 } 919 } 920 921 /** 922 * Sets the Hybrid UWB Session Controlee Configuration. 923 * 924 * <p>On successfully setting the hybrid Controlee configuration, 925 * {@link RangingSession.Callback#onHybridSessionControleeConfigured(PersistableBundle)} 926 * is invoked. 927 * 928 * <p>On failing to set the hybrid Controlee configuration, 929 * {@link RangingSession.Callback#onHybridSessionControleeConfigurationFailed(int, 930 * PersistableBundle)} is invoked. 931 * 932 * @param params protocol specific parameters to configure the hybrid session Controlee 933 * @throws RemoteException if a remote error occurred 934 */ 935 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) 936 @FlaggedApi("com.android.uwb.flags.hybrid_session_support") setHybridSessionControleeConfiguration(@onNull PersistableBundle params)937 public void setHybridSessionControleeConfiguration(@NonNull PersistableBundle params) { 938 if (!isOpen()) { 939 throw new IllegalStateException("Ranging session is not open"); 940 } 941 942 Log.v(mTag, "setHybridSessionControleeConfiguration - sessionHandle: " + mSessionHandle); 943 try { 944 mAdapter.setHybridSessionControleeConfiguration(mSessionHandle, params); 945 } catch (RemoteException e) { 946 throw e.rethrowFromSystemServer(); 947 } 948 } 949 950 /** 951 * @hide 952 */ onRangingOpened()953 public void onRangingOpened() { 954 if (mState == State.CLOSED) { 955 Log.w(mTag, "onRangingOpened invoked for a closed session"); 956 return; 957 } 958 959 Log.v(mTag, "onRangingOpened - sessionHandle: " + mSessionHandle); 960 mState = State.IDLE; 961 executeCallback(() -> mCallback.onOpened(this)); 962 } 963 964 /** 965 * @hide 966 */ onRangingOpenFailed(@allback.Reason int reason, @NonNull PersistableBundle params)967 public void onRangingOpenFailed(@Callback.Reason int reason, 968 @NonNull PersistableBundle params) { 969 if (mState == State.CLOSED) { 970 Log.w(mTag, "onRangingOpenFailed invoked for a closed session"); 971 return; 972 } 973 974 Log.v(mTag, "onRangingOpenFailed - sessionHandle: " + mSessionHandle); 975 mState = State.CLOSED; 976 executeCallback(() -> mCallback.onOpenFailed(reason, params)); 977 } 978 979 /** 980 * @hide 981 */ onRangingStarted(@onNull PersistableBundle parameters)982 public void onRangingStarted(@NonNull PersistableBundle parameters) { 983 if (mState == State.CLOSED) { 984 Log.w(mTag, "onRangingStarted invoked for a closed session"); 985 return; 986 } 987 988 Log.v(mTag, "onRangingStarted - sessionHandle: " + mSessionHandle); 989 mState = State.ACTIVE; 990 executeCallback(() -> mCallback.onStarted(parameters)); 991 } 992 993 /** 994 * @hide 995 */ onRangingStartFailed(@allback.Reason int reason, @NonNull PersistableBundle params)996 public void onRangingStartFailed(@Callback.Reason int reason, 997 @NonNull PersistableBundle params) { 998 if (mState == State.CLOSED) { 999 Log.w(mTag, "onRangingStartFailed invoked for a closed session"); 1000 return; 1001 } 1002 1003 Log.v(mTag, "onRangingStartFailed - sessionHandle: " + mSessionHandle); 1004 executeCallback(() -> mCallback.onStartFailed(reason, params)); 1005 } 1006 1007 /** 1008 * @hide 1009 */ onRangingReconfigured(@onNull PersistableBundle params)1010 public void onRangingReconfigured(@NonNull PersistableBundle params) { 1011 if (mState == State.CLOSED) { 1012 Log.w(mTag, "onRangingReconfigured invoked for a closed session"); 1013 return; 1014 } 1015 1016 Log.v(mTag, "onRangingReconfigured - sessionHandle: " + mSessionHandle); 1017 executeCallback(() -> mCallback.onReconfigured(params)); 1018 } 1019 1020 /** 1021 * @hide 1022 */ onRangingReconfigureFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1023 public void onRangingReconfigureFailed(@Callback.Reason int reason, 1024 @NonNull PersistableBundle params) { 1025 if (mState == State.CLOSED) { 1026 Log.w(mTag, "onRangingReconfigureFailed invoked for a closed session"); 1027 return; 1028 } 1029 1030 Log.v(mTag, "onRangingReconfigureFailed - sessionHandle: " + mSessionHandle); 1031 executeCallback(() -> mCallback.onReconfigureFailed(reason, params)); 1032 } 1033 1034 /** 1035 * @hide 1036 */ onRangingStopped(@allback.Reason int reason, @NonNull PersistableBundle params)1037 public void onRangingStopped(@Callback.Reason int reason, 1038 @NonNull PersistableBundle params) { 1039 if (mState == State.CLOSED) { 1040 Log.w(mTag, "onRangingStopped invoked for a closed session"); 1041 return; 1042 } 1043 1044 Log.v(mTag, "onRangingStopped - sessionHandle: " + mSessionHandle); 1045 mState = State.IDLE; 1046 executeCallback(() -> mCallback.onStopped(reason, params)); 1047 } 1048 1049 /** 1050 * @hide 1051 */ onRangingStopFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1052 public void onRangingStopFailed(@Callback.Reason int reason, 1053 @NonNull PersistableBundle params) { 1054 if (mState == State.CLOSED) { 1055 Log.w(mTag, "onRangingStopFailed invoked for a closed session"); 1056 return; 1057 } 1058 1059 Log.v(mTag, "onRangingStopFailed - sessionHandle: " + mSessionHandle); 1060 executeCallback(() -> mCallback.onStopFailed(reason, params)); 1061 } 1062 1063 /** 1064 * @hide 1065 */ onRangingClosed(@allback.Reason int reason, @NonNull PersistableBundle parameters)1066 public void onRangingClosed(@Callback.Reason int reason, 1067 @NonNull PersistableBundle parameters) { 1068 mState = State.CLOSED; 1069 Log.v(mTag, "onRangingClosed - sessionHandle: " + mSessionHandle); 1070 executeCallback(() -> mCallback.onClosed(reason, parameters)); 1071 } 1072 1073 /** 1074 * @hide 1075 */ onRangingResult(@onNull RangingReport report)1076 public void onRangingResult(@NonNull RangingReport report) { 1077 if (!isOpen()) { 1078 Log.w(mTag, "onRangingResult invoked for non-open session"); 1079 return; 1080 } 1081 1082 Log.v(mTag, "onRangingResult - sessionHandle: " + mSessionHandle); 1083 executeCallback(() -> mCallback.onReportReceived(report)); 1084 } 1085 1086 /** 1087 * @hide 1088 */ onControleeAdded(@onNull PersistableBundle params)1089 public void onControleeAdded(@NonNull PersistableBundle params) { 1090 if (!isOpen()) { 1091 Log.w(mTag, "onControleeAdded invoked for non-open session"); 1092 return; 1093 } 1094 1095 Log.v(mTag, "onControleeAdded - sessionHandle: " + mSessionHandle); 1096 executeCallback(() -> mCallback.onControleeAdded(params)); 1097 } 1098 1099 /** 1100 * @hide 1101 */ onControleeAddFailed(@allback.ControleeFailureReason int reason, @NonNull PersistableBundle params)1102 public void onControleeAddFailed(@Callback.ControleeFailureReason int reason, 1103 @NonNull PersistableBundle params) { 1104 if (!isOpen()) { 1105 Log.w(mTag, "onControleeAddFailed invoked for non-open session"); 1106 return; 1107 } 1108 1109 Log.v(mTag, "onControleeAddFailed - sessionHandle: " + mSessionHandle); 1110 executeCallback(() -> mCallback.onControleeAddFailed(reason, params)); 1111 } 1112 1113 /** 1114 * @hide 1115 */ onControleeRemoved(@onNull PersistableBundle params)1116 public void onControleeRemoved(@NonNull PersistableBundle params) { 1117 if (!isOpen()) { 1118 Log.w(mTag, "onControleeRemoved invoked for non-open session"); 1119 return; 1120 } 1121 1122 Log.v(mTag, "onControleeRemoved - sessionHandle: " + mSessionHandle); 1123 executeCallback(() -> mCallback.onControleeRemoved(params)); 1124 } 1125 1126 /** 1127 * @hide 1128 */ onControleeRemoveFailed(@allback.ControleeFailureReason int reason, @NonNull PersistableBundle params)1129 public void onControleeRemoveFailed(@Callback.ControleeFailureReason int reason, 1130 @NonNull PersistableBundle params) { 1131 if (!isOpen()) { 1132 Log.w(mTag, "onControleeRemoveFailed invoked for non-open session"); 1133 return; 1134 } 1135 1136 Log.v(mTag, "onControleeRemoveFailed - sessionHandle: " + mSessionHandle); 1137 executeCallback(() -> mCallback.onControleeRemoveFailed(reason, params)); 1138 } 1139 1140 /** 1141 * @hide 1142 */ onRangingPaused(@onNull PersistableBundle params)1143 public void onRangingPaused(@NonNull PersistableBundle params) { 1144 if (!isOpen()) { 1145 Log.w(mTag, "onRangingPaused invoked for non-open session"); 1146 return; 1147 } 1148 1149 Log.v(mTag, "onRangingPaused - sessionHandle: " + mSessionHandle); 1150 executeCallback(() -> mCallback.onPaused(params)); 1151 } 1152 1153 /** 1154 * @hide 1155 */ onRangingPauseFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1156 public void onRangingPauseFailed(@Callback.Reason int reason, 1157 @NonNull PersistableBundle params) { 1158 if (!isOpen()) { 1159 Log.w(mTag, "onRangingPauseFailed invoked for non-open session"); 1160 return; 1161 } 1162 1163 Log.v(mTag, "onRangingPauseFailed - sessionHandle: " + mSessionHandle); 1164 executeCallback(() -> mCallback.onPauseFailed(reason, params)); 1165 } 1166 1167 /** 1168 * @hide 1169 */ onRangingResumed(@onNull PersistableBundle params)1170 public void onRangingResumed(@NonNull PersistableBundle params) { 1171 if (!isOpen()) { 1172 Log.w(mTag, "onRangingResumed invoked for non-open session"); 1173 return; 1174 } 1175 1176 Log.v(mTag, "onRangingResumed - sessionHandle: " + mSessionHandle); 1177 executeCallback(() -> mCallback.onResumed(params)); 1178 } 1179 1180 /** 1181 * @hide 1182 */ onRangingResumeFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1183 public void onRangingResumeFailed(@Callback.Reason int reason, 1184 @NonNull PersistableBundle params) { 1185 if (!isOpen()) { 1186 Log.w(mTag, "onRangingResumeFailed invoked for non-open session"); 1187 return; 1188 } 1189 1190 Log.v(mTag, "onRangingResumeFailed - sessionHandle: " + mSessionHandle); 1191 executeCallback(() -> mCallback.onResumeFailed(reason, params)); 1192 } 1193 1194 /** 1195 * @hide 1196 */ onDataSent(@onNull UwbAddress remoteDeviceAddress, @NonNull PersistableBundle params)1197 public void onDataSent(@NonNull UwbAddress remoteDeviceAddress, 1198 @NonNull PersistableBundle params) { 1199 if (!isOpen()) { 1200 Log.w(mTag, "onDataSent invoked for non-open session"); 1201 return; 1202 } 1203 1204 Log.v(mTag, "onDataSent - sessionHandle: " + mSessionHandle); 1205 executeCallback(() -> mCallback.onDataSent(remoteDeviceAddress, params)); 1206 } 1207 1208 /** 1209 * @hide 1210 */ onDataSendFailed(@onNull UwbAddress remoteDeviceAddress, @Callback.DataFailureReason int reason, @NonNull PersistableBundle params)1211 public void onDataSendFailed(@NonNull UwbAddress remoteDeviceAddress, 1212 @Callback.DataFailureReason int reason, @NonNull PersistableBundle params) { 1213 if (!isOpen()) { 1214 Log.w(mTag, "onDataSendFailed invoked for non-open session"); 1215 return; 1216 } 1217 1218 Log.v(mTag, "onDataSendFailed - sessionHandle: " + mSessionHandle); 1219 executeCallback(() -> mCallback.onDataSendFailed(remoteDeviceAddress, reason, params)); 1220 } 1221 1222 /** 1223 * @hide 1224 */ onDataReceived(@onNull UwbAddress remoteDeviceAddress, @NonNull PersistableBundle params, @NonNull byte[] data)1225 public void onDataReceived(@NonNull UwbAddress remoteDeviceAddress, 1226 @NonNull PersistableBundle params, @NonNull byte[] data) { 1227 if (!isOpen()) { 1228 Log.w(mTag, "onDataReceived invoked for non-open session"); 1229 return; 1230 } 1231 1232 Log.v(mTag, "onDataReceived - sessionHandle: " + mSessionHandle); 1233 executeCallback(() -> mCallback.onDataReceived(remoteDeviceAddress, params, data)); 1234 } 1235 1236 /** 1237 * @hide 1238 */ onDataReceiveFailed(@onNull UwbAddress remoteDeviceAddress, @Callback.DataFailureReason int reason, @NonNull PersistableBundle params)1239 public void onDataReceiveFailed(@NonNull UwbAddress remoteDeviceAddress, 1240 @Callback.DataFailureReason int reason, @NonNull PersistableBundle params) { 1241 if (!isOpen()) { 1242 Log.w(mTag, "onDataReceiveFailed invoked for non-open session"); 1243 return; 1244 } 1245 1246 Log.v(mTag, "onDataReceiveFailed - sessionHandle: " + mSessionHandle); 1247 executeCallback(() -> mCallback.onDataReceiveFailed(remoteDeviceAddress, reason, params)); 1248 } 1249 1250 /** 1251 * @hide 1252 */ onDataTransferPhaseConfigured(@onNull PersistableBundle params)1253 public void onDataTransferPhaseConfigured(@NonNull PersistableBundle params) { 1254 if (!isOpen()) { 1255 Log.w(mTag, "onDataTransferPhaseConfigured invoked for non-open session"); 1256 return; 1257 } 1258 1259 Log.v(mTag, "onDataTransferPhaseConfigured - sessionHandle: " + mSessionHandle); 1260 executeCallback(() -> mCallback.onDataTransferPhaseConfigured(params)); 1261 } 1262 1263 /** 1264 * @hide 1265 */ onDataTransferPhaseConfigFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1266 public void onDataTransferPhaseConfigFailed(@Callback.Reason int reason, 1267 @NonNull PersistableBundle params) { 1268 if (!isOpen()) { 1269 Log.w(mTag, "onDataTransferPhaseConfigFailed invoked for non-open session"); 1270 return; 1271 } 1272 1273 Log.v(mTag, "onDataTransferPhaseConfigFailed - sessionHandle: " + mSessionHandle); 1274 executeCallback(() -> mCallback.onDataTransferPhaseConfigFailed(reason, params)); 1275 } 1276 1277 /** 1278 * @hide 1279 */ onServiceDiscovered(@onNull PersistableBundle params)1280 public void onServiceDiscovered(@NonNull PersistableBundle params) { 1281 if (!isOpen()) { 1282 Log.w(mTag, "onServiceDiscovered invoked for non-open session"); 1283 return; 1284 } 1285 1286 Log.v(mTag, "onServiceDiscovered - sessionHandle: " + mSessionHandle); 1287 executeCallback(() -> mCallback.onServiceDiscovered(params)); 1288 } 1289 1290 /** 1291 * @hide 1292 */ onServiceConnected(@onNull PersistableBundle params)1293 public void onServiceConnected(@NonNull PersistableBundle params) { 1294 if (!isOpen()) { 1295 Log.w(mTag, "onServiceConnected invoked for non-open session"); 1296 return; 1297 } 1298 1299 Log.v(mTag, "onServiceConnected - sessionHandle: " + mSessionHandle); 1300 executeCallback(() -> mCallback.onServiceConnected(params)); 1301 } 1302 1303 /** 1304 * @hide 1305 */ onRangingRoundsUpdateDtTagStatus(@onNull PersistableBundle params)1306 public void onRangingRoundsUpdateDtTagStatus(@NonNull PersistableBundle params) { 1307 if (!isOpen()) { 1308 Log.w(mTag, "onDlTDoARangingRoundsUpdateStatus invoked for non-open session"); 1309 return; 1310 } 1311 1312 Log.v(mTag, "onDlTDoARangingRoundsUpdateStatus - sessionHandle: " + mSessionHandle); 1313 if (SdkLevel.isAtLeastU()) { 1314 executeCallback(() -> mCallback.onRangingRoundsUpdateDtTagStatus(params)); 1315 } 1316 } 1317 1318 /** 1319 * @hide 1320 */ onHybridSessionControllerConfigured(@onNull PersistableBundle params)1321 public void onHybridSessionControllerConfigured(@NonNull PersistableBundle params) { 1322 if (!isOpen()) { 1323 Log.w(mTag, "onHybridSessionControllerConfigured invoked for non-open session"); 1324 return; 1325 } 1326 1327 Log.v(mTag, "onHybridSessionControllerConfigured - sessionHandle: " + mSessionHandle); 1328 executeCallback(() -> mCallback.onHybridSessionControllerConfigured(params)); 1329 } 1330 1331 /** 1332 * @hide 1333 */ onHybridSessionControllerConfigurationFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1334 public void onHybridSessionControllerConfigurationFailed(@Callback.Reason int reason, 1335 @NonNull PersistableBundle params) { 1336 if (!isOpen()) { 1337 Log.w(mTag, "onHybridSessionControllerConfigurationFailed invoked for non-open" 1338 + "session"); 1339 return; 1340 } 1341 1342 Log.v(mTag, "onHybridSessionControllerConfigurationFailed - sessionHandle: " 1343 + mSessionHandle); 1344 executeCallback(() -> mCallback.onHybridSessionControllerConfigurationFailed( 1345 reason, params)); 1346 } 1347 1348 /** 1349 * @hide 1350 */ onHybridSessionControleeConfigured(@onNull PersistableBundle params)1351 public void onHybridSessionControleeConfigured(@NonNull PersistableBundle params) { 1352 if (!isOpen()) { 1353 Log.w(mTag, "onHybridSessionControleeConfigured invoked for non-open session"); 1354 return; 1355 } 1356 1357 Log.v(mTag, "onHybridSessionControleeConfigured - sessionHandle: " + mSessionHandle); 1358 executeCallback(() -> mCallback.onHybridSessionControleeConfigured(params)); 1359 } 1360 1361 /** 1362 * @hide 1363 */ onHybridSessionControleeConfigurationFailed(@allback.Reason int reason, @NonNull PersistableBundle params)1364 public void onHybridSessionControleeConfigurationFailed(@Callback.Reason int reason, 1365 @NonNull PersistableBundle params) { 1366 if (!isOpen()) { 1367 Log.w(mTag, "onHybridSessionControleeConfigurationFailed invoked for non-open" 1368 + "session"); 1369 return; 1370 } 1371 1372 Log.v(mTag, "onHybridSessionControleeConfigurationFailed - sessionHandle: " 1373 + mSessionHandle); 1374 executeCallback(() -> mCallback.onHybridSessionControleeConfigurationFailed( 1375 reason, params)); 1376 } 1377 1378 /** 1379 * @hide 1380 */ executeCallback(@onNull Runnable runnable)1381 private void executeCallback(@NonNull Runnable runnable) { 1382 final long identity = Binder.clearCallingIdentity(); 1383 try { 1384 mExecutor.execute(runnable); 1385 } finally { 1386 Binder.restoreCallingIdentity(identity); 1387 } 1388 } 1389 1390 /** 1391 * Updates the UWB filter engine's pose information. This requires that the call to 1392 * {@link UwbManager#openRangingSession} indicated an application pose source. 1393 * 1394 * @param parameters Parameters representing the session to update, and the pose information. 1395 */ 1396 @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) updatePose(@onNull PersistableBundle parameters)1397 public void updatePose(@NonNull PersistableBundle parameters) { 1398 try { 1399 mAdapter.updatePose(mSessionHandle, parameters); 1400 } catch (RemoteException e) { 1401 throw e.rethrowFromSystemServer(); 1402 } 1403 } 1404 } 1405