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