RemoteConnection.java revision 0e094d926c306c3667bcdf6f23c52cc7181f25f3
1/* 2 * Copyright (C) 2014 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 17package android.telecom; 18 19import com.android.internal.telecom.IConnectionService; 20import com.android.internal.telecom.IVideoCallback; 21import com.android.internal.telecom.IVideoProvider; 22 23import android.annotation.SystemApi; 24import android.net.Uri; 25import android.os.IBinder; 26import android.os.RemoteException; 27import android.view.Surface; 28 29import java.util.ArrayList; 30import java.util.Collections; 31import java.util.List; 32import java.util.Set; 33import java.util.concurrent.ConcurrentHashMap; 34 35/** 36 * A connection provided to a {@link ConnectionService} by another {@code ConnectionService} 37 * running in a different process. 38 * 39 * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest) 40 * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest) 41 * @hide 42 */ 43@SystemApi 44public final class RemoteConnection { 45 46 public static abstract class Callback { 47 /** 48 * Invoked when the state of this {@code RemoteConnection} has changed. See 49 * {@link #getState()}. 50 * 51 * @param connection The {@code RemoteConnection} invoking this method. 52 * @param state The new state of the {@code RemoteConnection}. 53 */ 54 public void onStateChanged(RemoteConnection connection, int state) {} 55 56 /** 57 * Invoked when this {@code RemoteConnection} is disconnected. 58 * 59 * @param connection The {@code RemoteConnection} invoking this method. 60 * @param disconnectCause The ({@see DisconnectCause}) associated with this failed 61 * connection. 62 */ 63 public void onDisconnected( 64 RemoteConnection connection, 65 DisconnectCause disconnectCause) {} 66 67 /** 68 * Invoked when this {@code RemoteConnection} is requesting ringback. See 69 * {@link #isRingbackRequested()}. 70 * 71 * @param connection The {@code RemoteConnection} invoking this method. 72 * @param ringback Whether the {@code RemoteConnection} is requesting ringback. 73 */ 74 public void onRingbackRequested(RemoteConnection connection, boolean ringback) {} 75 76 /** 77 * Indicates that the call capabilities of this {@code RemoteConnection} have changed. 78 * See {@link #getCallCapabilities()}. 79 * 80 * @param connection The {@code RemoteConnection} invoking this method. 81 * @param callCapabilities The new call capabilities of the {@code RemoteConnection}. 82 */ 83 public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {} 84 85 /** 86 * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a 87 * pause character. This causes the post-dial signals to stop pending user confirmation. An 88 * implementation should present this choice to the user and invoke 89 * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice. 90 * 91 * @param connection The {@code RemoteConnection} invoking this method. 92 * @param remainingPostDialSequence The post-dial characters that remain to be sent. 93 */ 94 public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {} 95 96 /** 97 * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed. 98 * See {@link #isVoipAudioMode()}. 99 * 100 * @param connection The {@code RemoteConnection} invoking this method. 101 * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP. 102 */ 103 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {} 104 105 /** 106 * Indicates that the status hints of this {@code RemoteConnection} have changed. See 107 * {@link #getStatusHints()} ()}. 108 * 109 * @param connection The {@code RemoteConnection} invoking this method. 110 * @param statusHints The new status hints of the {@code RemoteConnection}. 111 */ 112 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {} 113 114 /** 115 * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has 116 * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}. 117 * 118 * @param connection The {@code RemoteConnection} invoking this method. 119 * @param address The new address of the {@code RemoteConnection}. 120 * @param presentation The presentation requirements for the address. 121 * See {@link TelecomManager} for valid values. 122 */ 123 public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {} 124 125 /** 126 * Indicates that the caller display name of this {@code RemoteConnection} has changed. 127 * See {@link #getCallerDisplayName()} and {@link #getCallerDisplayNamePresentation()}. 128 * 129 * @param connection The {@code RemoteConnection} invoking this method. 130 * @param callerDisplayName The new caller display name of the {@code RemoteConnection}. 131 * @param presentation The presentation requirements for the handle. 132 * See {@link TelecomManager} for valid values. 133 */ 134 public void onCallerDisplayNameChanged( 135 RemoteConnection connection, String callerDisplayName, int presentation) {} 136 137 /** 138 * Indicates that the video state of this {@code RemoteConnection} has changed. 139 * See {@link #getVideoState()}. 140 * 141 * @param connection The {@code RemoteConnection} invoking this method. 142 * @param videoState The new video state of the {@code RemoteConnection}. 143 * @hide 144 */ 145 public void onVideoStateChanged(RemoteConnection connection, int videoState) {} 146 147 /** 148 * Indicates that this {@code RemoteConnection} has been destroyed. No further requests 149 * should be made to the {@code RemoteConnection}, and references to it should be cleared. 150 * 151 * @param connection The {@code RemoteConnection} invoking this method. 152 */ 153 public void onDestroyed(RemoteConnection connection) {} 154 155 /** 156 * Indicates that the {@code RemoteConnection}s with which this {@code RemoteConnection} 157 * may be asked to create a conference has changed. 158 * 159 * @param connection The {@code RemoteConnection} invoking this method. 160 * @param conferenceableConnections The {@code RemoteConnection}s with which this 161 * {@code RemoteConnection} may be asked to create a conference. 162 */ 163 public void onConferenceableConnectionsChanged( 164 RemoteConnection connection, 165 List<RemoteConnection> conferenceableConnections) {} 166 167 /** 168 * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection} 169 * has changed. 170 * 171 * @param connection The {@code RemoteConnection} invoking this method. 172 * @param videoProvider The new {@code VideoProvider} associated with this 173 * {@code RemoteConnection}. 174 * @hide 175 */ 176 public void onVideoProviderChanged( 177 RemoteConnection connection, VideoProvider videoProvider) {} 178 179 /** 180 * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part 181 * of has changed. 182 * 183 * @param connection The {@code RemoteConnection} invoking this method. 184 * @param conference The {@code RemoteConference} of which this {@code RemoteConnection} is 185 * a part, which may be {@code null}. 186 */ 187 public void onConferenceChanged( 188 RemoteConnection connection, 189 RemoteConference conference) {} 190 } 191 192 /** {@hide} */ 193 public static class VideoProvider { 194 195 public abstract static class Listener { 196 public void onReceiveSessionModifyRequest( 197 VideoProvider videoProvider, 198 VideoProfile videoProfile) {} 199 200 public void onReceiveSessionModifyResponse( 201 VideoProvider videoProvider, 202 int status, 203 VideoProfile requestedProfile, 204 VideoProfile responseProfile) {} 205 206 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {} 207 208 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {} 209 210 public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {} 211 212 public void onCameraCapabilitiesChanged( 213 VideoProvider videoProvider, 214 CameraCapabilities cameraCapabilities) {} 215 } 216 217 private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() { 218 @Override 219 public void receiveSessionModifyRequest(VideoProfile videoProfile) { 220 for (Listener l : mListeners) { 221 l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile); 222 } 223 } 224 225 @Override 226 public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile, 227 VideoProfile responseProfile) { 228 for (Listener l : mListeners) { 229 l.onReceiveSessionModifyResponse( 230 VideoProvider.this, 231 status, 232 requestedProfile, 233 responseProfile); 234 } 235 } 236 237 @Override 238 public void handleCallSessionEvent(int event) { 239 for (Listener l : mListeners) { 240 l.onHandleCallSessionEvent(VideoProvider.this, event); 241 } 242 } 243 244 @Override 245 public void changePeerDimensions(int width, int height) { 246 for (Listener l : mListeners) { 247 l.onPeerDimensionsChanged(VideoProvider.this, width, height); 248 } 249 } 250 251 @Override 252 public void changeCallDataUsage(int dataUsage) { 253 for (Listener l : mListeners) { 254 l.onCallDataUsageChanged(VideoProvider.this, dataUsage); 255 } 256 } 257 258 @Override 259 public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { 260 for (Listener l : mListeners) { 261 l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities); 262 } 263 } 264 265 @Override 266 public IBinder asBinder() { 267 return null; 268 } 269 }; 270 271 private final VideoCallbackServant mVideoCallbackServant = 272 new VideoCallbackServant(mVideoCallbackDelegate); 273 274 private final IVideoProvider mVideoProviderBinder; 275 276 /** 277 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is 278 * load factor before resizing, 1 means we only expect a single thread to 279 * access the map so make only a single shard 280 */ 281 private final Set<Listener> mListeners = Collections.newSetFromMap( 282 new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); 283 284 public VideoProvider(IVideoProvider videoProviderBinder) { 285 mVideoProviderBinder = videoProviderBinder; 286 try { 287 mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder()); 288 } catch (RemoteException e) { 289 } 290 } 291 292 public void addListener(Listener l) { 293 mListeners.add(l); 294 } 295 296 public void removeListener(Listener l) { 297 mListeners.remove(l); 298 } 299 300 public void setCamera(String cameraId) { 301 try { 302 mVideoProviderBinder.setCamera(cameraId); 303 } catch (RemoteException e) { 304 } 305 } 306 307 public void setPreviewSurface(Surface surface) { 308 try { 309 mVideoProviderBinder.setPreviewSurface(surface); 310 } catch (RemoteException e) { 311 } 312 } 313 314 public void setDisplaySurface(Surface surface) { 315 try { 316 mVideoProviderBinder.setDisplaySurface(surface); 317 } catch (RemoteException e) { 318 } 319 } 320 321 public void setDeviceOrientation(int rotation) { 322 try { 323 mVideoProviderBinder.setDeviceOrientation(rotation); 324 } catch (RemoteException e) { 325 } 326 } 327 328 public void setZoom(float value) { 329 try { 330 mVideoProviderBinder.setZoom(value); 331 } catch (RemoteException e) { 332 } 333 } 334 335 public void sendSessionModifyRequest(VideoProfile reqProfile) { 336 try { 337 mVideoProviderBinder.sendSessionModifyRequest(reqProfile); 338 } catch (RemoteException e) { 339 } 340 } 341 342 public void sendSessionModifyResponse(VideoProfile responseProfile) { 343 try { 344 mVideoProviderBinder.sendSessionModifyResponse(responseProfile); 345 } catch (RemoteException e) { 346 } 347 } 348 349 public void requestCameraCapabilities() { 350 try { 351 mVideoProviderBinder.requestCameraCapabilities(); 352 } catch (RemoteException e) { 353 } 354 } 355 356 public void requestCallDataUsage() { 357 try { 358 mVideoProviderBinder.requestCallDataUsage(); 359 } catch (RemoteException e) { 360 } 361 } 362 363 public void setPauseImage(String uri) { 364 try { 365 mVideoProviderBinder.setPauseImage(uri); 366 } catch (RemoteException e) { 367 } 368 } 369 } 370 371 private IConnectionService mConnectionService; 372 private final String mConnectionId; 373 /** 374 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is 375 * load factor before resizing, 1 means we only expect a single thread to 376 * access the map so make only a single shard 377 */ 378 private final Set<Callback> mCallbacks = Collections.newSetFromMap( 379 new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1)); 380 private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>(); 381 private final List<RemoteConnection> mUnmodifiableconferenceableConnections = 382 Collections.unmodifiableList(mConferenceableConnections); 383 384 private int mState = Connection.STATE_NEW; 385 private DisconnectCause mDisconnectCause; 386 private boolean mRingbackRequested; 387 private boolean mConnected; 388 private int mCallCapabilities; 389 private int mVideoState; 390 private VideoProvider mVideoProvider; 391 private boolean mIsVoipAudioMode; 392 private StatusHints mStatusHints; 393 private Uri mAddress; 394 private int mAddressPresentation; 395 private String mCallerDisplayName; 396 private int mCallerDisplayNamePresentation; 397 private RemoteConference mConference; 398 399 /** 400 * @hide 401 */ 402 RemoteConnection( 403 String id, 404 IConnectionService connectionService, 405 ConnectionRequest request) { 406 mConnectionId = id; 407 mConnectionService = connectionService; 408 mConnected = true; 409 mState = Connection.STATE_INITIALIZING; 410 } 411 412 /** 413 * @hide 414 */ 415 RemoteConnection(String callId, IConnectionService connectionService, 416 ParcelableConnection connection) { 417 mConnectionId = callId; 418 mConnectionService = connectionService; 419 mConnected = true; 420 mState = connection.getState(); 421 mDisconnectCause = connection.getDisconnectCause(); 422 mRingbackRequested = connection.isRingbackRequested(); 423 mCallCapabilities = connection.getCapabilities(); 424 mVideoState = connection.getVideoState(); 425 mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider()); 426 mIsVoipAudioMode = connection.getIsVoipAudioMode(); 427 mStatusHints = connection.getStatusHints(); 428 mAddress = connection.getHandle(); 429 mAddressPresentation = connection.getHandlePresentation(); 430 mCallerDisplayName = connection.getCallerDisplayName(); 431 mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation(); 432 mConference = null; 433 } 434 435 /** 436 * Create a RemoteConnection which is used for failed connections. Note that using it for any 437 * "real" purpose will almost certainly fail. Callers should note the failure and act 438 * accordingly (moving on to another RemoteConnection, for example) 439 * 440 * @param disconnectCause The reason for the failed connection. 441 * @hide 442 */ 443 RemoteConnection(DisconnectCause disconnectCause) { 444 mConnectionId = "NULL"; 445 mConnected = false; 446 mState = Connection.STATE_DISCONNECTED; 447 mDisconnectCause = disconnectCause; 448 } 449 450 /** 451 * Adds a callback to this {@code RemoteConnection}. 452 * 453 * @param callback A {@code Callback}. 454 */ 455 public void registerCallback(Callback callback) { 456 mCallbacks.add(callback); 457 } 458 459 /** 460 * Removes a callback from this {@code RemoteConnection}. 461 * 462 * @param callback A {@code Callback}. 463 */ 464 public void unregisterCallback(Callback callback) { 465 if (callback != null) { 466 mCallbacks.remove(callback); 467 } 468 } 469 470 /** 471 * Obtains the state of this {@code RemoteConnection}. 472 * 473 * @return A state value, chosen from the {@code STATE_*} constants. 474 */ 475 public int getState() { 476 return mState; 477 } 478 479 /** 480 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the 481 * disconnect cause expressed as a code chosen from among those declared in 482 * {@link DisconnectCause}. 483 */ 484 public DisconnectCause getDisconnectCause() { 485 return mDisconnectCause; 486 } 487 488 /** 489 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in 490 * {@link PhoneCapabilities}. 491 */ 492 public int getCallCapabilities() { 493 return mCallCapabilities; 494 } 495 496 /** 497 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP. 498 */ 499 public boolean isVoipAudioMode() { 500 return mIsVoipAudioMode; 501 } 502 503 /** 504 * @return The current {@link StatusHints} of this {@code RemoteConnection}, 505 * or {@code null} if none have been set. 506 */ 507 public StatusHints getStatusHints() { 508 return mStatusHints; 509 } 510 511 /** 512 * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently 513 * connected. 514 */ 515 public Uri getAddress() { 516 return mAddress; 517 } 518 519 /** 520 * @return The presentation requirements for the address. See {@link TelecomManager} for valid 521 * values. 522 */ 523 public int getAddressPresentation() { 524 return mAddressPresentation; 525 } 526 527 /** 528 * @return The display name for the caller. 529 */ 530 public CharSequence getCallerDisplayName() { 531 return mCallerDisplayName; 532 } 533 534 /** 535 * @return The presentation requirements for the caller display name. See 536 * {@link TelecomManager} for valid values. 537 */ 538 public int getCallerDisplayNamePresentation() { 539 return mCallerDisplayNamePresentation; 540 } 541 542 /** 543 * @return The video state of the {@code RemoteConnection}. See 544 * {@link VideoProfile.VideoState}. 545 * @hide 546 */ 547 public int getVideoState() { 548 return mVideoState; 549 } 550 551 /** 552 * @return The video provider associated with this {@code RemoteConnection}. 553 * @hide 554 */ 555 public final VideoProvider getVideoProvider() { 556 return mVideoProvider; 557 } 558 559 /** 560 * @return Whether the {@code RemoteConnection} is requesting that the framework play a 561 * ringback tone on its behalf. 562 */ 563 public boolean isRingbackRequested() { 564 return false; 565 } 566 567 /** 568 * Instructs this {@code RemoteConnection} to abort. 569 */ 570 public void abort() { 571 try { 572 if (mConnected) { 573 mConnectionService.abort(mConnectionId); 574 } 575 } catch (RemoteException ignored) { 576 } 577 } 578 579 /** 580 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. 581 */ 582 public void answer() { 583 try { 584 if (mConnected) { 585 mConnectionService.answer(mConnectionId); 586 } 587 } catch (RemoteException ignored) { 588 } 589 } 590 591 /** 592 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. 593 * @param videoState The video state in which to answer the call. 594 * @hide 595 */ 596 public void answer(int videoState) { 597 try { 598 if (mConnected) { 599 mConnectionService.answerVideo(mConnectionId, videoState); 600 } 601 } catch (RemoteException ignored) { 602 } 603 } 604 605 /** 606 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject. 607 */ 608 public void reject() { 609 try { 610 if (mConnected) { 611 mConnectionService.reject(mConnectionId); 612 } 613 } catch (RemoteException ignored) { 614 } 615 } 616 617 /** 618 * Instructs this {@code RemoteConnection} to go on hold. 619 */ 620 public void hold() { 621 try { 622 if (mConnected) { 623 mConnectionService.hold(mConnectionId); 624 } 625 } catch (RemoteException ignored) { 626 } 627 } 628 629 /** 630 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold. 631 */ 632 public void unhold() { 633 try { 634 if (mConnected) { 635 mConnectionService.unhold(mConnectionId); 636 } 637 } catch (RemoteException ignored) { 638 } 639 } 640 641 /** 642 * Instructs this {@code RemoteConnection} to disconnect. 643 */ 644 public void disconnect() { 645 try { 646 if (mConnected) { 647 mConnectionService.disconnect(mConnectionId); 648 } 649 } catch (RemoteException ignored) { 650 } 651 } 652 653 /** 654 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling 655 * (DTMF) tone. 656 * 657 * Any other currently playing DTMF tone in the specified call is immediately stopped. 658 * 659 * @param digit A character representing the DTMF digit for which to play the tone. This 660 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}. 661 */ 662 public void playDtmfTone(char digit) { 663 try { 664 if (mConnected) { 665 mConnectionService.playDtmfTone(mConnectionId, digit); 666 } 667 } catch (RemoteException ignored) { 668 } 669 } 670 671 /** 672 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling 673 * (DTMF) tone currently playing. 674 * 675 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is 676 * currently playing, this method will do nothing. 677 */ 678 public void stopDtmfTone() { 679 try { 680 if (mConnected) { 681 mConnectionService.stopDtmfTone(mConnectionId); 682 } 683 } catch (RemoteException ignored) { 684 } 685 } 686 687 /** 688 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string. 689 * 690 * A post-dial DTMF string is a string of digits following the first instance of either 691 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}. 692 * These digits are immediately sent as DTMF tones to the recipient as soon as the 693 * connection is made. 694 * 695 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this 696 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period 697 * of time. 698 * 699 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this 700 * {@code RemoteConnection} will pause playing the tones and notify callbackss via 701 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app 702 * should display to the user an indication of this state and an affordance to continue 703 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call 704 * app should invoke the {@link #postDialContinue(boolean)} method. 705 * 706 * @param proceed Whether or not to continue with the post-dial sequence. 707 */ 708 public void postDialContinue(boolean proceed) { 709 try { 710 if (mConnected) { 711 mConnectionService.onPostDialContinue(mConnectionId, proceed); 712 } 713 } catch (RemoteException ignored) { 714 } 715 } 716 717 /** 718 * Set the audio state of this {@code RemoteConnection}. 719 * 720 * @param state The audio state of this {@code RemoteConnection}. 721 */ 722 public void setAudioState(AudioState state) { 723 try { 724 if (mConnected) { 725 mConnectionService.onAudioStateChanged(mConnectionId, state); 726 } 727 } catch (RemoteException ignored) { 728 } 729 } 730 731 /** 732 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be 733 * successfully asked to create a conference with. 734 * 735 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be 736 * merged into a {@link RemoteConference}. 737 */ 738 public List<RemoteConnection> getConferenceableConnections() { 739 return mUnmodifiableconferenceableConnections; 740 } 741 742 /** 743 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part 744 * of, or {@code null} if there is no such {@code RemoteConference}. 745 * 746 * @return A {@code RemoteConference} or {@code null}; 747 */ 748 public RemoteConference getConference() { 749 return mConference; 750 } 751 752 /** {@hide} */ 753 String getId() { 754 return mConnectionId; 755 } 756 757 /** {@hide} */ 758 IConnectionService getConnectionService() { 759 return mConnectionService; 760 } 761 762 /** 763 * @hide 764 */ 765 void setState(int state) { 766 if (mState != state) { 767 mState = state; 768 for (Callback c: mCallbacks) { 769 c.onStateChanged(this, state); 770 } 771 } 772 } 773 774 /** 775 * @hide 776 */ 777 void setDisconnected(DisconnectCause disconnectCause) { 778 if (mState != Connection.STATE_DISCONNECTED) { 779 mState = Connection.STATE_DISCONNECTED; 780 mDisconnectCause = disconnectCause; 781 782 for (Callback c : mCallbacks) { 783 c.onDisconnected(this, mDisconnectCause); 784 } 785 } 786 } 787 788 /** 789 * @hide 790 */ 791 void setRingbackRequested(boolean ringback) { 792 if (mRingbackRequested != ringback) { 793 mRingbackRequested = ringback; 794 for (Callback c : mCallbacks) { 795 c.onRingbackRequested(this, ringback); 796 } 797 } 798 } 799 800 /** 801 * @hide 802 */ 803 void setCallCapabilities(int callCapabilities) { 804 mCallCapabilities = callCapabilities; 805 for (Callback c : mCallbacks) { 806 c.onCallCapabilitiesChanged(this, callCapabilities); 807 } 808 } 809 810 /** 811 * @hide 812 */ 813 void setDestroyed() { 814 if (!mCallbacks.isEmpty()) { 815 // Make sure that the callbacks are notified that the call is destroyed first. 816 if (mState != Connection.STATE_DISCONNECTED) { 817 setDisconnected( 818 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed.")); 819 } 820 821 for (Callback c : mCallbacks) { 822 c.onDestroyed(this); 823 } 824 mCallbacks.clear(); 825 826 mConnected = false; 827 } 828 } 829 830 /** 831 * @hide 832 */ 833 void setPostDialWait(String remainingDigits) { 834 for (Callback c : mCallbacks) { 835 c.onPostDialWait(this, remainingDigits); 836 } 837 } 838 839 /** 840 * @hide 841 */ 842 void setVideoState(int videoState) { 843 mVideoState = videoState; 844 for (Callback c : mCallbacks) { 845 c.onVideoStateChanged(this, videoState); 846 } 847 } 848 849 /** 850 * @hide 851 */ 852 void setVideoProvider(VideoProvider videoProvider) { 853 mVideoProvider = videoProvider; 854 for (Callback c : mCallbacks) { 855 c.onVideoProviderChanged(this, videoProvider); 856 } 857 } 858 859 /** @hide */ 860 void setIsVoipAudioMode(boolean isVoip) { 861 mIsVoipAudioMode = isVoip; 862 for (Callback c : mCallbacks) { 863 c.onVoipAudioChanged(this, isVoip); 864 } 865 } 866 867 /** @hide */ 868 void setStatusHints(StatusHints statusHints) { 869 mStatusHints = statusHints; 870 for (Callback c : mCallbacks) { 871 c.onStatusHintsChanged(this, statusHints); 872 } 873 } 874 875 /** @hide */ 876 void setAddress(Uri address, int presentation) { 877 mAddress = address; 878 mAddressPresentation = presentation; 879 for (Callback c : mCallbacks) { 880 c.onAddressChanged(this, address, presentation); 881 } 882 } 883 884 /** @hide */ 885 void setCallerDisplayName(String callerDisplayName, int presentation) { 886 mCallerDisplayName = callerDisplayName; 887 mCallerDisplayNamePresentation = presentation; 888 for (Callback c : mCallbacks) { 889 c.onCallerDisplayNameChanged(this, callerDisplayName, presentation); 890 } 891 } 892 893 /** @hide */ 894 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) { 895 mConferenceableConnections.clear(); 896 mConferenceableConnections.addAll(conferenceableConnections); 897 for (Callback c : mCallbacks) { 898 c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections); 899 } 900 } 901 902 /** @hide */ 903 void setConference(RemoteConference conference) { 904 if (mConference != conference) { 905 mConference = conference; 906 for (Callback c : mCallbacks) { 907 c.onConferenceChanged(this, conference); 908 } 909 } 910 } 911 912 /** 913 * Create a RemoteConnection represents a failure, and which will be in 914 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost 915 * certainly result in bad things happening. Do not do this. 916 * 917 * @return a failed {@link RemoteConnection} 918 * 919 * @hide 920 */ 921 public static RemoteConnection failure(DisconnectCause disconnectCause) { 922 return new RemoteConnection(disconnectCause); 923 } 924} 925