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