1 /* 2 * Copyright (C) 2018 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.telephony.ims; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.os.Message; 22 import android.os.RemoteException; 23 import android.telephony.CallQuality; 24 import android.telephony.ims.aidl.IImsCallSessionListener; 25 import android.util.ArraySet; 26 import android.util.Log; 27 28 import com.android.ims.internal.IImsCallSession; 29 import com.android.ims.internal.IImsVideoCallProvider; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 import java.util.Set; 34 35 /** 36 * Provides the call initiation/termination, and media exchange between two IMS endpoints. 37 * It directly communicates with IMS service which implements the IMS protocol behavior. 38 * 39 * @hide 40 */ 41 public class ImsCallSession { 42 private static final String TAG = "ImsCallSession"; 43 44 /** 45 * Defines IMS call session state. Please use 46 * {@link android.telephony.ims.stub.ImsCallSessionImplBase.State} definition. 47 * This is kept around for capability reasons. 48 */ 49 public static class State { 50 public static final int IDLE = 0; 51 public static final int INITIATED = 1; 52 public static final int NEGOTIATING = 2; 53 public static final int ESTABLISHING = 3; 54 public static final int ESTABLISHED = 4; 55 56 public static final int RENEGOTIATING = 5; 57 public static final int REESTABLISHING = 6; 58 59 public static final int TERMINATING = 7; 60 public static final int TERMINATED = 8; 61 62 public static final int INVALID = (-1); 63 64 /** 65 * Converts the state to string. 66 */ toString(int state)67 public static String toString(int state) { 68 switch (state) { 69 case IDLE: 70 return "IDLE"; 71 case INITIATED: 72 return "INITIATED"; 73 case NEGOTIATING: 74 return "NEGOTIATING"; 75 case ESTABLISHING: 76 return "ESTABLISHING"; 77 case ESTABLISHED: 78 return "ESTABLISHED"; 79 case RENEGOTIATING: 80 return "RENEGOTIATING"; 81 case REESTABLISHING: 82 return "REESTABLISHING"; 83 case TERMINATING: 84 return "TERMINATING"; 85 case TERMINATED: 86 return "TERMINATED"; 87 default: 88 return "UNKNOWN"; 89 } 90 } 91 State()92 private State() { 93 } 94 } 95 96 /** 97 * Listener for events relating to an IMS session, such as when a session is being 98 * recieved ("on ringing") or a call is outgoing ("on calling"). 99 * <p>Many of these events are also received by {@link ImsCall.Listener}.</p> 100 * @hide 101 */ 102 public static class Listener { 103 /** 104 * Called when the session is initiating. 105 * 106 * see: {@link ImsCallSessionListener#callSessionInitiating(ImsCallProfile)} 107 */ callSessionInitiating(ImsCallSession session, ImsCallProfile profile)108 public void callSessionInitiating(ImsCallSession session, 109 ImsCallProfile profile) { 110 // no-op 111 } 112 113 /** 114 * Called when the session failed before initiating was called. 115 * 116 * see: {@link ImsCallSessionListener#callSessionInitiatingFailed(ImsReasonInfo)} 117 */ callSessionInitiatingFailed(ImsCallSession session, ImsReasonInfo reasonInfo)118 public void callSessionInitiatingFailed(ImsCallSession session, 119 ImsReasonInfo reasonInfo) { 120 // no-op 121 } 122 123 /** 124 * Called when the session is progressing. 125 * 126 * see: {@link ImsCallSessionListener#callSessionProgressing(ImsStreamMediaProfile)} 127 */ callSessionProgressing(ImsCallSession session, ImsStreamMediaProfile profile)128 public void callSessionProgressing(ImsCallSession session, 129 ImsStreamMediaProfile profile) { 130 // no-op 131 } 132 133 /** 134 * Called when the session is established. 135 * 136 * @param session the session object that carries out the IMS session 137 */ callSessionStarted(ImsCallSession session, ImsCallProfile profile)138 public void callSessionStarted(ImsCallSession session, 139 ImsCallProfile profile) { 140 // no-op 141 } 142 143 /** 144 * Called when the session establishment is failed. 145 * 146 * @param session the session object that carries out the IMS session 147 * @param reasonInfo detailed reason of the session establishment failure 148 */ callSessionStartFailed(ImsCallSession session, ImsReasonInfo reasonInfo)149 public void callSessionStartFailed(ImsCallSession session, 150 ImsReasonInfo reasonInfo) { 151 } 152 153 /** 154 * Called when the session is terminated. 155 * 156 * @param session the session object that carries out the IMS session 157 * @param reasonInfo detailed reason of the session termination 158 */ callSessionTerminated(ImsCallSession session, ImsReasonInfo reasonInfo)159 public void callSessionTerminated(ImsCallSession session, 160 ImsReasonInfo reasonInfo) { 161 } 162 163 /** 164 * Called when the session is in hold. 165 * 166 * @param session the session object that carries out the IMS session 167 */ callSessionHeld(ImsCallSession session, ImsCallProfile profile)168 public void callSessionHeld(ImsCallSession session, 169 ImsCallProfile profile) { 170 } 171 172 /** 173 * Called when the session hold is failed. 174 * 175 * @param session the session object that carries out the IMS session 176 * @param reasonInfo detailed reason of the session hold failure 177 */ callSessionHoldFailed(ImsCallSession session, ImsReasonInfo reasonInfo)178 public void callSessionHoldFailed(ImsCallSession session, 179 ImsReasonInfo reasonInfo) { 180 } 181 182 /** 183 * Called when the session hold is received from the remote user. 184 * 185 * @param session the session object that carries out the IMS session 186 */ callSessionHoldReceived(ImsCallSession session, ImsCallProfile profile)187 public void callSessionHoldReceived(ImsCallSession session, 188 ImsCallProfile profile) { 189 } 190 191 /** 192 * Called when the session resume is done. 193 * 194 * @param session the session object that carries out the IMS session 195 */ callSessionResumed(ImsCallSession session, ImsCallProfile profile)196 public void callSessionResumed(ImsCallSession session, 197 ImsCallProfile profile) { 198 } 199 200 /** 201 * Called when the session resume is failed. 202 * 203 * @param session the session object that carries out the IMS session 204 * @param reasonInfo detailed reason of the session resume failure 205 */ callSessionResumeFailed(ImsCallSession session, ImsReasonInfo reasonInfo)206 public void callSessionResumeFailed(ImsCallSession session, 207 ImsReasonInfo reasonInfo) { 208 } 209 210 /** 211 * Called when the session resume is received from the remote user. 212 * 213 * @param session the session object that carries out the IMS session 214 */ callSessionResumeReceived(ImsCallSession session, ImsCallProfile profile)215 public void callSessionResumeReceived(ImsCallSession session, 216 ImsCallProfile profile) { 217 } 218 219 /** 220 * Called when the session merge has been started. At this point, the {@code newSession} 221 * represents the session which has been initiated to the IMS conference server for the 222 * new merged conference. 223 * 224 * @param session the session object that carries out the IMS session 225 * @param newSession the session object that is merged with an active & hold session 226 */ callSessionMergeStarted(ImsCallSession session, ImsCallSession newSession, ImsCallProfile profile)227 public void callSessionMergeStarted(ImsCallSession session, 228 ImsCallSession newSession, ImsCallProfile profile) { 229 } 230 231 /** 232 * Called when the session merge is successful and the merged session is active. 233 * 234 * @param session the session object that carries out the IMS session 235 */ callSessionMergeComplete(ImsCallSession session)236 public void callSessionMergeComplete(ImsCallSession session) { 237 } 238 239 /** 240 * Called when the session merge has failed. 241 * 242 * @param session the session object that carries out the IMS session 243 * @param reasonInfo detailed reason of the call merge failure 244 */ callSessionMergeFailed(ImsCallSession session, ImsReasonInfo reasonInfo)245 public void callSessionMergeFailed(ImsCallSession session, 246 ImsReasonInfo reasonInfo) { 247 } 248 249 /** 250 * Called when the session is updated (except for hold/unhold). 251 * 252 * @param session the session object that carries out the IMS session 253 */ callSessionUpdated(ImsCallSession session, ImsCallProfile profile)254 public void callSessionUpdated(ImsCallSession session, 255 ImsCallProfile profile) { 256 } 257 258 /** 259 * Called when the session update is failed. 260 * 261 * @param session the session object that carries out the IMS session 262 * @param reasonInfo detailed reason of the session update failure 263 */ callSessionUpdateFailed(ImsCallSession session, ImsReasonInfo reasonInfo)264 public void callSessionUpdateFailed(ImsCallSession session, 265 ImsReasonInfo reasonInfo) { 266 } 267 268 /** 269 * Called when the session update is received from the remote user. 270 * 271 * @param session the session object that carries out the IMS session 272 */ callSessionUpdateReceived(ImsCallSession session, ImsCallProfile profile)273 public void callSessionUpdateReceived(ImsCallSession session, 274 ImsCallProfile profile) { 275 // no-op 276 } 277 278 /** 279 * Called when the session is extended to the conference session. 280 * 281 * @param session the session object that carries out the IMS session 282 * @param newSession the session object that is extended to the conference 283 * from the active session 284 */ callSessionConferenceExtended(ImsCallSession session, ImsCallSession newSession, ImsCallProfile profile)285 public void callSessionConferenceExtended(ImsCallSession session, 286 ImsCallSession newSession, ImsCallProfile profile) { 287 } 288 289 /** 290 * Called when the conference extension is failed. 291 * 292 * @param session the session object that carries out the IMS session 293 * @param reasonInfo detailed reason of the conference extension failure 294 */ callSessionConferenceExtendFailed(ImsCallSession session, ImsReasonInfo reasonInfo)295 public void callSessionConferenceExtendFailed(ImsCallSession session, 296 ImsReasonInfo reasonInfo) { 297 } 298 299 /** 300 * Called when the conference extension is received from the remote user. 301 * 302 * @param session the session object that carries out the IMS session 303 */ callSessionConferenceExtendReceived(ImsCallSession session, ImsCallSession newSession, ImsCallProfile profile)304 public void callSessionConferenceExtendReceived(ImsCallSession session, 305 ImsCallSession newSession, ImsCallProfile profile) { 306 // no-op 307 } 308 309 /** 310 * Called when the invitation request of the participants is delivered to the conference 311 * server. 312 * 313 * @param session the session object that carries out the IMS session 314 */ callSessionInviteParticipantsRequestDelivered(ImsCallSession session)315 public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) { 316 // no-op 317 } 318 319 /** 320 * Called when the invitation request of the participants is failed. 321 * 322 * @param session the session object that carries out the IMS session 323 * @param reasonInfo detailed reason of the conference invitation failure 324 */ callSessionInviteParticipantsRequestFailed(ImsCallSession session, ImsReasonInfo reasonInfo)325 public void callSessionInviteParticipantsRequestFailed(ImsCallSession session, 326 ImsReasonInfo reasonInfo) { 327 // no-op 328 } 329 330 /** 331 * Called when the removal request of the participants is delivered to the conference 332 * server. 333 * 334 * @param session the session object that carries out the IMS session 335 */ callSessionRemoveParticipantsRequestDelivered(ImsCallSession session)336 public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) { 337 // no-op 338 } 339 340 /** 341 * Called when the removal request of the participants is failed. 342 * 343 * @param session the session object that carries out the IMS session 344 * @param reasonInfo detailed reason of the conference removal failure 345 */ callSessionRemoveParticipantsRequestFailed(ImsCallSession session, ImsReasonInfo reasonInfo)346 public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session, 347 ImsReasonInfo reasonInfo) { 348 // no-op 349 } 350 351 /** 352 * Called when the conference state is updated. 353 * 354 * @param session the session object that carries out the IMS session 355 */ callSessionConferenceStateUpdated(ImsCallSession session, ImsConferenceState state)356 public void callSessionConferenceStateUpdated(ImsCallSession session, 357 ImsConferenceState state) { 358 // no-op 359 } 360 361 /** 362 * Called when the USSD message is received from the network. 363 * 364 * @param mode mode of the USSD message (REQUEST / NOTIFY) 365 * @param ussdMessage USSD message 366 */ callSessionUssdMessageReceived(ImsCallSession session, int mode, String ussdMessage)367 public void callSessionUssdMessageReceived(ImsCallSession session, 368 int mode, String ussdMessage) { 369 // no-op 370 } 371 372 /** 373 * Called when an {@link ImsCallSession} may handover from one network type to another. 374 * For example, the session may handover from WIFI to LTE if conditions are right. 375 * <p> 376 * If handover is attempted, 377 * {@link #callSessionHandover(ImsCallSession, int, int, ImsReasonInfo)} or 378 * {@link #callSessionHandoverFailed(ImsCallSession, int, int, ImsReasonInfo)} will be 379 * called to indicate the success or failure of the handover. 380 * 381 * @param session IMS session object 382 * @param srcNetworkType original network type 383 * @param targetNetworkType new network type 384 */ callSessionMayHandover(ImsCallSession session, int srcNetworkType, int targetNetworkType)385 public void callSessionMayHandover(ImsCallSession session, int srcNetworkType, 386 int targetNetworkType) { 387 // no-op 388 } 389 390 /** 391 * Called when session network type changes 392 * 393 * @param session IMS session object 394 * @param srcNetworkType original network type 395 * @param targetNetworkType new network type 396 * @param reasonInfo 397 */ callSessionHandover(ImsCallSession session, int srcNetworkType, int targetNetworkType, ImsReasonInfo reasonInfo)398 public void callSessionHandover(ImsCallSession session, 399 int srcNetworkType, int targetNetworkType, 400 ImsReasonInfo reasonInfo) { 401 // no-op 402 } 403 404 /** 405 * Called when session access technology change fails 406 * 407 * @param session IMS session object 408 * @param srcNetworkType original access technology 409 * @param targetNetworkType new access technology 410 * @param reasonInfo handover failure reason 411 */ callSessionHandoverFailed(ImsCallSession session, int srcNetworkType, int targetNetworkType, ImsReasonInfo reasonInfo)412 public void callSessionHandoverFailed(ImsCallSession session, 413 int srcNetworkType, int targetNetworkType, 414 ImsReasonInfo reasonInfo) { 415 // no-op 416 } 417 418 /** 419 * Called when TTY mode of remote party changed 420 * 421 * @param session IMS session object 422 * @param mode TTY mode of remote party 423 */ callSessionTtyModeReceived(ImsCallSession session, int mode)424 public void callSessionTtyModeReceived(ImsCallSession session, 425 int mode) { 426 // no-op 427 } 428 429 /** 430 * Notifies of a change to the multiparty state for this {@code ImsCallSession}. 431 * 432 * @param session The call session. 433 * @param isMultiParty {@code true} if the session became multiparty, {@code false} 434 * otherwise. 435 */ callSessionMultipartyStateChanged(ImsCallSession session, boolean isMultiParty)436 public void callSessionMultipartyStateChanged(ImsCallSession session, 437 boolean isMultiParty) { 438 // no-op 439 } 440 441 /** 442 * Called when the session supplementary service is received 443 * 444 * @param session the session object that carries out the IMS session 445 */ callSessionSuppServiceReceived(ImsCallSession session, ImsSuppServiceNotification suppServiceInfo)446 public void callSessionSuppServiceReceived(ImsCallSession session, 447 ImsSuppServiceNotification suppServiceInfo) { 448 } 449 450 /** 451 * Received RTT modify request from Remote Party 452 */ callSessionRttModifyRequestReceived(ImsCallSession session, ImsCallProfile callProfile)453 public void callSessionRttModifyRequestReceived(ImsCallSession session, 454 ImsCallProfile callProfile) { 455 // no-op 456 } 457 458 /** 459 * Received response for RTT modify request 460 */ callSessionRttModifyResponseReceived(int status)461 public void callSessionRttModifyResponseReceived(int status) { 462 // no -op 463 } 464 465 /** 466 * Device received RTT message from Remote UE 467 */ callSessionRttMessageReceived(String rttMessage)468 public void callSessionRttMessageReceived(String rttMessage) { 469 // no-op 470 } 471 472 /** 473 * While in call, there has been a change in RTT audio indicator. 474 */ callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile)475 public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) { 476 // no-op 477 } 478 479 /** 480 * Received success response for call transfer request. 481 */ callSessionTransferred(@onNull ImsCallSession session)482 public void callSessionTransferred(@NonNull ImsCallSession session) { 483 // no-op 484 } 485 486 /** 487 * Received failure response for call transfer request. 488 */ callSessionTransferFailed(@onNull ImsCallSession session, @Nullable ImsReasonInfo reasonInfo)489 public void callSessionTransferFailed(@NonNull ImsCallSession session, 490 @Nullable ImsReasonInfo reasonInfo) { 491 // no-op 492 } 493 494 /** 495 * Informs the framework of a DTMF digit which was received from the network. 496 * <p> 497 * According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>, 498 * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 499 * 12 ~ 15. 500 * @param digit the DTMF digit 501 */ callSessionDtmfReceived(char digit)502 public void callSessionDtmfReceived(char digit) { 503 // no-op 504 } 505 506 /** 507 * Called when the IMS service reports a change to the call quality. 508 */ callQualityChanged(CallQuality callQuality)509 public void callQualityChanged(CallQuality callQuality) { 510 // no-op 511 } 512 513 /** 514 * Called when the IMS service reports incoming RTP header extension data. 515 */ callSessionRtpHeaderExtensionsReceived( @onNull Set<RtpHeaderExtension> extensions)516 public void callSessionRtpHeaderExtensionsReceived( 517 @NonNull Set<RtpHeaderExtension> extensions) { 518 // no-op 519 } 520 } 521 522 private final IImsCallSession miSession; 523 private boolean mClosed = false; 524 private Listener mListener; 525 526 /** @hide */ ImsCallSession(IImsCallSession iSession)527 public ImsCallSession(IImsCallSession iSession) { 528 miSession = iSession; 529 530 if (iSession != null) { 531 try { 532 iSession.setListener(new IImsCallSessionListenerProxy()); 533 } catch (RemoteException e) { 534 } 535 } else { 536 mClosed = true; 537 } 538 } 539 540 /** @hide */ ImsCallSession(IImsCallSession iSession, Listener listener)541 public ImsCallSession(IImsCallSession iSession, Listener listener) { 542 this(iSession); 543 setListener(listener); 544 } 545 546 /** 547 * Closes this object. This object is not usable after being closed. 548 */ close()549 public void close() { 550 synchronized (this) { 551 if (mClosed) { 552 return; 553 } 554 555 try { 556 miSession.close(); 557 mClosed = true; 558 } catch (RemoteException e) { 559 } 560 } 561 } 562 563 /** 564 * Gets the call ID of the session. 565 * 566 * @return the call ID 567 */ getCallId()568 public String getCallId() { 569 if (mClosed) { 570 return null; 571 } 572 573 try { 574 return miSession.getCallId(); 575 } catch (RemoteException e) { 576 return null; 577 } 578 } 579 580 /** 581 * Gets the call profile that this session is associated with 582 * 583 * @return the call profile that this session is associated with 584 */ getCallProfile()585 public ImsCallProfile getCallProfile() { 586 if (mClosed) { 587 return null; 588 } 589 590 try { 591 return miSession.getCallProfile(); 592 } catch (RemoteException e) { 593 return null; 594 } 595 } 596 597 /** 598 * Gets the local call profile that this session is associated with 599 * 600 * @return the local call profile that this session is associated with 601 */ getLocalCallProfile()602 public ImsCallProfile getLocalCallProfile() { 603 if (mClosed) { 604 return null; 605 } 606 607 try { 608 return miSession.getLocalCallProfile(); 609 } catch (RemoteException e) { 610 return null; 611 } 612 } 613 614 /** 615 * Gets the remote call profile that this session is associated with 616 * 617 * @return the remote call profile that this session is associated with 618 */ getRemoteCallProfile()619 public ImsCallProfile getRemoteCallProfile() { 620 if (mClosed) { 621 return null; 622 } 623 624 try { 625 return miSession.getRemoteCallProfile(); 626 } catch (RemoteException e) { 627 return null; 628 } 629 } 630 631 /** 632 * Gets the video call provider for the session. 633 * 634 * @return The video call provider. 635 * @hide 636 */ getVideoCallProvider()637 public IImsVideoCallProvider getVideoCallProvider() { 638 if (mClosed) { 639 return null; 640 } 641 642 try { 643 return miSession.getVideoCallProvider(); 644 } catch (RemoteException e) { 645 return null; 646 } 647 } 648 649 /** 650 * Gets the value associated with the specified property of this session. 651 * 652 * @return the string value associated with the specified property 653 */ getProperty(String name)654 public String getProperty(String name) { 655 if (mClosed) { 656 return null; 657 } 658 659 try { 660 return miSession.getProperty(name); 661 } catch (RemoteException e) { 662 return null; 663 } 664 } 665 666 /** 667 * Gets the session state. 668 * The value returned must be one of the states in {@link State}. 669 * 670 * @return the session state 671 */ getState()672 public int getState() { 673 if (mClosed) { 674 return State.INVALID; 675 } 676 677 try { 678 return miSession.getState(); 679 } catch (RemoteException e) { 680 return State.INVALID; 681 } 682 } 683 684 /** 685 * Determines if the {@link ImsCallSession} is currently alive (e.g. not in a terminated or 686 * closed state). 687 * 688 * @return {@code True} if the session is alive. 689 */ isAlive()690 public boolean isAlive() { 691 if (mClosed) { 692 return false; 693 } 694 695 int state = getState(); 696 switch (state) { 697 case State.IDLE: 698 case State.INITIATED: 699 case State.NEGOTIATING: 700 case State.ESTABLISHING: 701 case State.ESTABLISHED: 702 case State.RENEGOTIATING: 703 case State.REESTABLISHING: 704 return true; 705 default: 706 return false; 707 } 708 } 709 710 /** 711 * Gets the native IMS call session. 712 * @hide 713 */ getSession()714 public IImsCallSession getSession() { 715 return miSession; 716 } 717 718 /** 719 * Checks if the session is in call. 720 * 721 * @return true if the session is in call 722 */ isInCall()723 public boolean isInCall() { 724 if (mClosed) { 725 return false; 726 } 727 728 try { 729 return miSession.isInCall(); 730 } catch (RemoteException e) { 731 return false; 732 } 733 } 734 735 /** 736 * Sets the listener to listen to the session events. A {@link ImsCallSession} 737 * can only hold one listener at a time. Subsequent calls to this method 738 * override the previous listener. 739 * 740 * @param listener to listen to the session events of this object 741 * @hide 742 */ setListener(Listener listener)743 public void setListener(Listener listener) { 744 mListener = listener; 745 } 746 747 /** 748 * Mutes or unmutes the mic for the active call. 749 * 750 * @param muted true if the call is muted, false otherwise 751 */ setMute(boolean muted)752 public void setMute(boolean muted) { 753 if (mClosed) { 754 return; 755 } 756 757 try { 758 miSession.setMute(muted); 759 } catch (RemoteException e) { 760 } 761 } 762 763 /** 764 * Initiates an IMS call with the specified target and call profile. 765 * The session listener is called back upon defined session events. 766 * The method is only valid to call when the session state is in 767 * {@link ImsCallSession.State#IDLE}. 768 * 769 * @param callee dialed string to make the call to 770 * @param profile call profile to make the call with the specified service type, 771 * call type and media information 772 * @see Listener#callSessionStarted, Listener#callSessionStartFailed 773 */ start(String callee, ImsCallProfile profile)774 public void start(String callee, ImsCallProfile profile) { 775 if (mClosed) { 776 return; 777 } 778 779 try { 780 miSession.start(callee, profile); 781 } catch (RemoteException e) { 782 } 783 } 784 785 /** 786 * Initiates an IMS conference call with the specified target and call profile. 787 * The session listener is called back upon defined session events. 788 * The method is only valid to call when the session state is in 789 * {@link ImsCallSession.State#IDLE}. 790 * 791 * @param participants participant list to initiate an IMS conference call 792 * @param profile call profile to make the call with the specified service type, 793 * call type and media information 794 * @see Listener#callSessionStarted, Listener#callSessionStartFailed 795 */ start(String[] participants, ImsCallProfile profile)796 public void start(String[] participants, ImsCallProfile profile) { 797 if (mClosed) { 798 return; 799 } 800 801 try { 802 miSession.startConference(participants, profile); 803 } catch (RemoteException e) { 804 } 805 } 806 807 /** 808 * Accepts an incoming call or session update. 809 * 810 * @param callType call type specified in {@link ImsCallProfile} to be answered 811 * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered 812 * @see Listener#callSessionStarted 813 */ accept(int callType, ImsStreamMediaProfile profile)814 public void accept(int callType, ImsStreamMediaProfile profile) { 815 if (mClosed) { 816 return; 817 } 818 819 try { 820 miSession.accept(callType, profile); 821 } catch (RemoteException e) { 822 } 823 } 824 825 /** 826 * Deflects an incoming call. 827 * 828 * @param number number to be deflected to 829 */ deflect(String number)830 public void deflect(String number) { 831 if (mClosed) { 832 return; 833 } 834 835 try { 836 miSession.deflect(number); 837 } catch (RemoteException e) { 838 } 839 } 840 841 /** 842 * Rejects an incoming call or session update. 843 * 844 * @param reason reason code to reject an incoming call 845 * @see Listener#callSessionStartFailed 846 */ reject(int reason)847 public void reject(int reason) { 848 if (mClosed) { 849 return; 850 } 851 852 try { 853 miSession.reject(reason); 854 } catch (RemoteException e) { 855 } 856 } 857 858 /** 859 * Transfers an ongoing call. 860 * 861 * @param number number to be transferred to. 862 * @param isConfirmationRequired indicates whether confirmation of the transfer is required. 863 */ transfer(@onNull String number, boolean isConfirmationRequired)864 public void transfer(@NonNull String number, boolean isConfirmationRequired) { 865 if (mClosed) { 866 return; 867 } 868 869 try { 870 miSession.transfer(number, isConfirmationRequired); 871 } catch (RemoteException e) { 872 } 873 } 874 875 /** 876 * Transfers a call to another ongoing call. 877 * 878 * @param transferToSession the other ImsCallSession to which this session will be transferred. 879 */ transfer(@onNull ImsCallSession transferToSession)880 public void transfer(@NonNull ImsCallSession transferToSession) { 881 if (mClosed) { 882 return; 883 } 884 885 try { 886 if (transferToSession != null) { 887 miSession.consultativeTransfer(transferToSession.getSession()); 888 } 889 } catch (RemoteException e) { 890 } 891 } 892 893 /** 894 * Terminates a call. 895 * 896 * @see Listener#callSessionTerminated 897 */ terminate(int reason)898 public void terminate(int reason) { 899 if (mClosed) { 900 return; 901 } 902 903 try { 904 miSession.terminate(reason); 905 } catch (RemoteException e) { 906 } 907 } 908 909 /** 910 * Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called. 911 * 912 * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call 913 * @see Listener#callSessionHeld, Listener#callSessionHoldFailed 914 */ hold(ImsStreamMediaProfile profile)915 public void hold(ImsStreamMediaProfile profile) { 916 if (mClosed) { 917 return; 918 } 919 920 try { 921 miSession.hold(profile); 922 } catch (RemoteException e) { 923 } 924 } 925 926 /** 927 * Continues a call that's on hold. When it succeeds, 928 * {@link Listener#callSessionResumed} is called. 929 * 930 * @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call 931 * @see Listener#callSessionResumed, Listener#callSessionResumeFailed 932 */ resume(ImsStreamMediaProfile profile)933 public void resume(ImsStreamMediaProfile profile) { 934 if (mClosed) { 935 return; 936 } 937 938 try { 939 miSession.resume(profile); 940 } catch (RemoteException e) { 941 } 942 } 943 944 /** 945 * Merges the active & hold call. When it succeeds, 946 * {@link Listener#callSessionMergeStarted} is called. 947 * 948 * @see Listener#callSessionMergeStarted , Listener#callSessionMergeFailed 949 */ merge()950 public void merge() { 951 if (mClosed) { 952 return; 953 } 954 955 try { 956 miSession.merge(); 957 } catch (RemoteException e) { 958 } 959 } 960 961 /** 962 * Updates the current call's properties (ex. call mode change: video upgrade / downgrade). 963 * 964 * @param callType call type specified in {@link ImsCallProfile} to be updated 965 * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated 966 * @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed 967 */ update(int callType, ImsStreamMediaProfile profile)968 public void update(int callType, ImsStreamMediaProfile profile) { 969 if (mClosed) { 970 return; 971 } 972 973 try { 974 miSession.update(callType, profile); 975 } catch (RemoteException e) { 976 } 977 } 978 979 /** 980 * Extends this call to the conference call with the specified recipients. 981 * 982 * @param participants list to be invited to the conference call after extending the call 983 * @see Listener#callSessionConferenceExtended 984 * @see Listener#callSessionConferenceExtendFailed 985 */ extendToConference(String[] participants)986 public void extendToConference(String[] participants) { 987 if (mClosed) { 988 return; 989 } 990 991 try { 992 miSession.extendToConference(participants); 993 } catch (RemoteException e) { 994 } 995 } 996 997 /** 998 * Requests the conference server to invite an additional participants to the conference. 999 * 1000 * @param participants list to be invited to the conference call 1001 * @see Listener#callSessionInviteParticipantsRequestDelivered 1002 * @see Listener#callSessionInviteParticipantsRequestFailed 1003 */ inviteParticipants(String[] participants)1004 public void inviteParticipants(String[] participants) { 1005 if (mClosed) { 1006 return; 1007 } 1008 1009 try { 1010 miSession.inviteParticipants(participants); 1011 } catch (RemoteException e) { 1012 } 1013 } 1014 1015 /** 1016 * Requests the conference server to remove the specified participants from the conference. 1017 * 1018 * @param participants participant list to be removed from the conference call 1019 * @see Listener#callSessionRemoveParticipantsRequestDelivered 1020 * @see Listener#callSessionRemoveParticipantsRequestFailed 1021 */ removeParticipants(String[] participants)1022 public void removeParticipants(String[] participants) { 1023 if (mClosed) { 1024 return; 1025 } 1026 1027 try { 1028 miSession.removeParticipants(participants); 1029 } catch (RemoteException e) { 1030 } 1031 } 1032 1033 1034 /** 1035 * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, 1036 * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, 1037 * and event flash to 16. Currently, event flash is not supported. 1038 * 1039 * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. 1040 */ sendDtmf(char c, Message result)1041 public void sendDtmf(char c, Message result) { 1042 if (mClosed) { 1043 return; 1044 } 1045 1046 try { 1047 miSession.sendDtmf(c, result); 1048 } catch (RemoteException e) { 1049 } 1050 } 1051 1052 /** 1053 * Starts a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, 1054 * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, 1055 * and event flash to 16. Currently, event flash is not supported. 1056 * 1057 * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. 1058 */ startDtmf(char c)1059 public void startDtmf(char c) { 1060 if (mClosed) { 1061 return; 1062 } 1063 1064 try { 1065 miSession.startDtmf(c); 1066 } catch (RemoteException e) { 1067 } 1068 } 1069 1070 /** 1071 * Stops a DTMF code. 1072 */ stopDtmf()1073 public void stopDtmf() { 1074 if (mClosed) { 1075 return; 1076 } 1077 1078 try { 1079 miSession.stopDtmf(); 1080 } catch (RemoteException e) { 1081 } 1082 } 1083 1084 /** 1085 * Sends an USSD message. 1086 * 1087 * @param ussdMessage USSD message to send 1088 */ sendUssd(String ussdMessage)1089 public void sendUssd(String ussdMessage) { 1090 if (mClosed) { 1091 return; 1092 } 1093 1094 try { 1095 miSession.sendUssd(ussdMessage); 1096 } catch (RemoteException e) { 1097 } 1098 } 1099 1100 /** 1101 * Determines if the session is multiparty. 1102 * 1103 * @return {@code True} if the session is multiparty. 1104 */ isMultiparty()1105 public boolean isMultiparty() { 1106 if (mClosed) { 1107 return false; 1108 } 1109 1110 try { 1111 return miSession.isMultiparty(); 1112 } catch (RemoteException e) { 1113 return false; 1114 } 1115 } 1116 1117 /** 1118 * Sends Rtt Message 1119 * 1120 * @param rttMessage rtt text to be sent 1121 */ sendRttMessage(String rttMessage)1122 public void sendRttMessage(String rttMessage) { 1123 if (mClosed) { 1124 return; 1125 } 1126 1127 try { 1128 miSession.sendRttMessage(rttMessage); 1129 } catch (RemoteException e) { 1130 } 1131 } 1132 1133 /** 1134 * Sends RTT Upgrade or downgrade request 1135 * 1136 * @param to Profile with the RTT flag set to the desired value 1137 */ sendRttModifyRequest(ImsCallProfile to)1138 public void sendRttModifyRequest(ImsCallProfile to) { 1139 if (mClosed) { 1140 return; 1141 } 1142 1143 try { 1144 miSession.sendRttModifyRequest(to); 1145 } catch (RemoteException e) { 1146 } 1147 } 1148 1149 /** 1150 * Sends RTT Upgrade response 1151 * 1152 * @param response : response for upgrade 1153 */ sendRttModifyResponse(boolean response)1154 public void sendRttModifyResponse(boolean response) { 1155 if (mClosed) { 1156 return; 1157 } 1158 1159 try { 1160 miSession.sendRttModifyResponse(response); 1161 } catch (RemoteException e) { 1162 } 1163 } 1164 1165 /** 1166 * Requests that {@code rtpHeaderExtensions} are sent as a header extension with the next 1167 * RTP packet sent by the IMS stack. 1168 * <p> 1169 * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol) 1170 * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method. 1171 * See RFC8285 for more information. 1172 * <p> 1173 * By specification, the RTP header extension is an unacknowledged transmission and there is no 1174 * guarantee that the header extension will be delivered by the network to the other end of the 1175 * call. 1176 * @param rtpHeaderExtensions The header extensions to be included in the next RTP header. 1177 */ sendRtpHeaderExtensions(@onNull Set<RtpHeaderExtension> rtpHeaderExtensions)1178 public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) { 1179 if (mClosed) { 1180 return; 1181 } 1182 1183 try { 1184 miSession.sendRtpHeaderExtensions( 1185 new ArrayList<RtpHeaderExtension>(rtpHeaderExtensions)); 1186 } catch (RemoteException e) { 1187 } 1188 } 1189 1190 /** 1191 * A listener type for receiving notification on IMS call session events. 1192 * When an event is generated for an {@link IImsCallSession}, 1193 * the application is notified by having one of the methods called on 1194 * the {@link IImsCallSessionListener}. 1195 */ 1196 private class IImsCallSessionListenerProxy extends IImsCallSessionListener.Stub { 1197 /** 1198 * Notifies the result of the basic session operation (setup / terminate). 1199 */ 1200 @Override callSessionInitiating(ImsCallProfile profile)1201 public void callSessionInitiating(ImsCallProfile profile) { 1202 if (mListener != null) { 1203 mListener.callSessionInitiating(ImsCallSession.this, profile); 1204 } 1205 } 1206 1207 @Override callSessionProgressing(ImsStreamMediaProfile profile)1208 public void callSessionProgressing(ImsStreamMediaProfile profile) { 1209 if (mListener != null) { 1210 mListener.callSessionProgressing(ImsCallSession.this, profile); 1211 } 1212 } 1213 1214 @Override callSessionInitiated(ImsCallProfile profile)1215 public void callSessionInitiated(ImsCallProfile profile) { 1216 if (mListener != null) { 1217 mListener.callSessionStarted(ImsCallSession.this, profile); 1218 } 1219 } 1220 1221 @Override callSessionInitiatingFailed(ImsReasonInfo reasonInfo)1222 public void callSessionInitiatingFailed(ImsReasonInfo reasonInfo) { 1223 if (mListener != null) { 1224 mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); 1225 } 1226 } 1227 1228 @Override callSessionInitiatedFailed(ImsReasonInfo reasonInfo)1229 public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { 1230 if (mListener != null) { 1231 mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); 1232 } 1233 } 1234 1235 @Override callSessionTerminated(ImsReasonInfo reasonInfo)1236 public void callSessionTerminated(ImsReasonInfo reasonInfo) { 1237 if (mListener != null) { 1238 mListener.callSessionTerminated(ImsCallSession.this, reasonInfo); 1239 } 1240 } 1241 1242 /** 1243 * Notifies the result of the call hold/resume operation. 1244 */ 1245 @Override callSessionHeld(ImsCallProfile profile)1246 public void callSessionHeld(ImsCallProfile profile) { 1247 if (mListener != null) { 1248 mListener.callSessionHeld(ImsCallSession.this, profile); 1249 } 1250 } 1251 1252 @Override callSessionHoldFailed(ImsReasonInfo reasonInfo)1253 public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { 1254 if (mListener != null) { 1255 mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo); 1256 } 1257 } 1258 1259 @Override callSessionHoldReceived(ImsCallProfile profile)1260 public void callSessionHoldReceived(ImsCallProfile profile) { 1261 if (mListener != null) { 1262 mListener.callSessionHoldReceived(ImsCallSession.this, profile); 1263 } 1264 } 1265 1266 @Override callSessionResumed(ImsCallProfile profile)1267 public void callSessionResumed(ImsCallProfile profile) { 1268 if (mListener != null) { 1269 mListener.callSessionResumed(ImsCallSession.this, profile); 1270 } 1271 } 1272 1273 @Override callSessionResumeFailed(ImsReasonInfo reasonInfo)1274 public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { 1275 if (mListener != null) { 1276 mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo); 1277 } 1278 } 1279 1280 @Override callSessionResumeReceived(ImsCallProfile profile)1281 public void callSessionResumeReceived(ImsCallProfile profile) { 1282 if (mListener != null) { 1283 mListener.callSessionResumeReceived(ImsCallSession.this, profile); 1284 } 1285 } 1286 1287 /** 1288 * Notifies the start of a call merge operation. 1289 * 1290 * @param newSession The merged call session. 1291 * @param profile The call profile. 1292 */ 1293 @Override callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile)1294 public void callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile) { 1295 // This callback can be used for future use to add additional 1296 // functionality that may be needed between conference start and complete 1297 Log.d(TAG, "callSessionMergeStarted"); 1298 } 1299 1300 /** 1301 * Notifies the successful completion of a call merge operation. 1302 * 1303 * @param newSession The call session. 1304 */ 1305 @Override callSessionMergeComplete(IImsCallSession newSession)1306 public void callSessionMergeComplete(IImsCallSession newSession) { 1307 if (mListener != null) { 1308 if (newSession != null) { 1309 // New session created after conference 1310 mListener.callSessionMergeComplete(new ImsCallSession(newSession)); 1311 } else { 1312 // Session already exists. Hence no need to pass 1313 mListener.callSessionMergeComplete(null); 1314 } 1315 } 1316 } 1317 1318 /** 1319 * Notifies of a failure to perform a call merge operation. 1320 * 1321 * @param reasonInfo The merge failure reason. 1322 */ 1323 @Override callSessionMergeFailed(ImsReasonInfo reasonInfo)1324 public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { 1325 if (mListener != null) { 1326 mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo); 1327 } 1328 } 1329 1330 /** 1331 * Notifies the result of call upgrade / downgrade or any other call updates. 1332 */ 1333 @Override callSessionUpdated(ImsCallProfile profile)1334 public void callSessionUpdated(ImsCallProfile profile) { 1335 if (mListener != null) { 1336 mListener.callSessionUpdated(ImsCallSession.this, profile); 1337 } 1338 } 1339 1340 @Override callSessionUpdateFailed(ImsReasonInfo reasonInfo)1341 public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { 1342 if (mListener != null) { 1343 mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo); 1344 } 1345 } 1346 1347 @Override callSessionUpdateReceived(ImsCallProfile profile)1348 public void callSessionUpdateReceived(ImsCallProfile profile) { 1349 if (mListener != null) { 1350 mListener.callSessionUpdateReceived(ImsCallSession.this, profile); 1351 } 1352 } 1353 1354 /** 1355 * Notifies the result of conference extension. 1356 */ 1357 @Override callSessionConferenceExtended(IImsCallSession newSession, ImsCallProfile profile)1358 public void callSessionConferenceExtended(IImsCallSession newSession, 1359 ImsCallProfile profile) { 1360 if (mListener != null) { 1361 mListener.callSessionConferenceExtended(ImsCallSession.this, 1362 new ImsCallSession(newSession), profile); 1363 } 1364 } 1365 1366 @Override callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo)1367 public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { 1368 if (mListener != null) { 1369 mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo); 1370 } 1371 } 1372 1373 @Override callSessionConferenceExtendReceived(IImsCallSession newSession, ImsCallProfile profile)1374 public void callSessionConferenceExtendReceived(IImsCallSession newSession, 1375 ImsCallProfile profile) { 1376 if (mListener != null) { 1377 mListener.callSessionConferenceExtendReceived(ImsCallSession.this, 1378 new ImsCallSession(newSession), profile); 1379 } 1380 } 1381 1382 /** 1383 * Notifies the result of the participant invitation / removal to/from 1384 * the conference session. 1385 */ 1386 @Override callSessionInviteParticipantsRequestDelivered()1387 public void callSessionInviteParticipantsRequestDelivered() { 1388 if (mListener != null) { 1389 mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this); 1390 } 1391 } 1392 1393 @Override callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo)1394 public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) { 1395 if (mListener != null) { 1396 mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this, 1397 reasonInfo); 1398 } 1399 } 1400 1401 @Override callSessionRemoveParticipantsRequestDelivered()1402 public void callSessionRemoveParticipantsRequestDelivered() { 1403 if (mListener != null) { 1404 mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this); 1405 } 1406 } 1407 1408 @Override callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo)1409 public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) { 1410 if (mListener != null) { 1411 mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this, 1412 reasonInfo); 1413 } 1414 } 1415 1416 /** 1417 * Notifies the changes of the conference info. in the conference session. 1418 */ 1419 @Override callSessionConferenceStateUpdated(ImsConferenceState state)1420 public void callSessionConferenceStateUpdated(ImsConferenceState state) { 1421 if (mListener != null) { 1422 mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state); 1423 } 1424 } 1425 1426 /** 1427 * Notifies the incoming USSD message. 1428 */ 1429 @Override callSessionUssdMessageReceived(int mode, String ussdMessage)1430 public void callSessionUssdMessageReceived(int mode, String ussdMessage) { 1431 if (mListener != null) { 1432 mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage); 1433 } 1434 } 1435 1436 /** 1437 * Notifies of a case where a {@link ImsCallSession} may 1438 * potentially handover from one radio technology to another. 1439 * @param srcNetworkType The source network type; one of the network type constants defined 1440 * in {@link android.telephony.TelephonyManager}. For example 1441 * {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}. 1442 * @param targetNetworkType The target radio access technology; one of the network type 1443 * constants defined in {@link android.telephony.TelephonyManager}. 1444 * For example 1445 * {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}. 1446 */ 1447 @Override callSessionMayHandover(int srcNetworkType, int targetNetworkType)1448 public void callSessionMayHandover(int srcNetworkType, int targetNetworkType) { 1449 if (mListener != null) { 1450 mListener.callSessionMayHandover(ImsCallSession.this, srcNetworkType, 1451 targetNetworkType); 1452 } 1453 } 1454 1455 /** 1456 * Notifies of handover information for this call 1457 */ 1458 @Override callSessionHandover(int srcNetworkType, int targetNetworkType, ImsReasonInfo reasonInfo)1459 public void callSessionHandover(int srcNetworkType, int targetNetworkType, 1460 ImsReasonInfo reasonInfo) { 1461 if (mListener != null) { 1462 mListener.callSessionHandover(ImsCallSession.this, srcNetworkType, 1463 targetNetworkType, reasonInfo); 1464 } 1465 } 1466 1467 /** 1468 * Notifies of handover failure info for this call 1469 */ 1470 @Override callSessionHandoverFailed(int srcNetworkType, int targetNetworkType, ImsReasonInfo reasonInfo)1471 public void callSessionHandoverFailed(int srcNetworkType, int targetNetworkType, 1472 ImsReasonInfo reasonInfo) { 1473 if (mListener != null) { 1474 mListener.callSessionHandoverFailed(ImsCallSession.this, srcNetworkType, 1475 targetNetworkType, reasonInfo); 1476 } 1477 } 1478 1479 /** 1480 * Notifies the TTY mode received from remote party. 1481 */ 1482 @Override callSessionTtyModeReceived(int mode)1483 public void callSessionTtyModeReceived(int mode) { 1484 if (mListener != null) { 1485 mListener.callSessionTtyModeReceived(ImsCallSession.this, mode); 1486 } 1487 } 1488 1489 /** 1490 * Notifies of a change to the multiparty state for this {@code ImsCallSession}. 1491 * 1492 * @param isMultiParty {@code true} if the session became multiparty, {@code false} 1493 * otherwise. 1494 */ callSessionMultipartyStateChanged(boolean isMultiParty)1495 public void callSessionMultipartyStateChanged(boolean isMultiParty) { 1496 if (mListener != null) { 1497 mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty); 1498 } 1499 } 1500 1501 @Override callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo )1502 public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo ) { 1503 if (mListener != null) { 1504 mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo); 1505 } 1506 } 1507 1508 /** 1509 * Received RTT modify request from remote party 1510 */ 1511 @Override callSessionRttModifyRequestReceived(ImsCallProfile callProfile)1512 public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) { 1513 if (mListener != null) { 1514 mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile); 1515 } 1516 } 1517 1518 /** 1519 * Received response for RTT modify request 1520 */ 1521 @Override callSessionRttModifyResponseReceived(int status)1522 public void callSessionRttModifyResponseReceived(int status) { 1523 if (mListener != null) { 1524 mListener.callSessionRttModifyResponseReceived(status); 1525 } 1526 } 1527 1528 /** 1529 * RTT Message received 1530 */ 1531 @Override callSessionRttMessageReceived(String rttMessage)1532 public void callSessionRttMessageReceived(String rttMessage) { 1533 if (mListener != null) { 1534 mListener.callSessionRttMessageReceived(rttMessage); 1535 } 1536 } 1537 1538 /** 1539 * While in call, there has been a change in RTT audio indicator. 1540 */ 1541 @Override callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile)1542 public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) { 1543 if (mListener != null) { 1544 mListener.callSessionRttAudioIndicatorChanged(profile); 1545 } 1546 } 1547 1548 @Override callSessionTransferred()1549 public void callSessionTransferred() { 1550 if (mListener != null) { 1551 mListener.callSessionTransferred(ImsCallSession.this); 1552 } 1553 } 1554 1555 @Override callSessionTransferFailed(@ullable ImsReasonInfo reasonInfo)1556 public void callSessionTransferFailed(@Nullable ImsReasonInfo reasonInfo) { 1557 if (mListener != null) { 1558 mListener.callSessionTransferFailed(ImsCallSession.this, reasonInfo); 1559 } 1560 } 1561 1562 /** 1563 * DTMF digit received. 1564 * @param dtmf The DTMF digit. 1565 */ 1566 @Override callSessionDtmfReceived(char dtmf)1567 public void callSessionDtmfReceived(char dtmf) { 1568 if (mListener != null) { 1569 mListener.callSessionDtmfReceived(dtmf); 1570 } 1571 } 1572 1573 /** 1574 * Call quality updated 1575 */ 1576 @Override callQualityChanged(CallQuality callQuality)1577 public void callQualityChanged(CallQuality callQuality) { 1578 if (mListener != null) { 1579 mListener.callQualityChanged(callQuality); 1580 } 1581 } 1582 1583 /** 1584 * RTP header extension data received. 1585 * @param extensions The header extension data. 1586 */ 1587 @Override callSessionRtpHeaderExtensionsReceived( @onNull List<RtpHeaderExtension> extensions)1588 public void callSessionRtpHeaderExtensionsReceived( 1589 @NonNull List<RtpHeaderExtension> extensions) { 1590 if (mListener != null) { 1591 mListener.callSessionRtpHeaderExtensionsReceived( 1592 new ArraySet<RtpHeaderExtension>(extensions)); 1593 } 1594 } 1595 } 1596 1597 /** 1598 * Provides a string representation of the {@link ImsCallSession}. Primarily intended for 1599 * use in log statements. 1600 * 1601 * @return String representation of session. 1602 */ 1603 @Override toString()1604 public String toString() { 1605 StringBuilder sb = new StringBuilder(); 1606 sb.append("[ImsCallSession objId:"); 1607 sb.append(System.identityHashCode(this)); 1608 sb.append(" state:"); 1609 sb.append(State.toString(getState())); 1610 sb.append(" callId:"); 1611 sb.append(getCallId()); 1612 sb.append("]"); 1613 return sb.toString(); 1614 } 1615 } 1616