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