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 17 package android.telecom; 18 19 import com.android.internal.telecom.IConnectionService; 20 import com.android.internal.telecom.IVideoCallback; 21 import com.android.internal.telecom.IVideoProvider; 22 23 import android.annotation.SystemApi; 24 import android.net.Uri; 25 import android.os.IBinder; 26 import android.os.RemoteException; 27 import android.view.Surface; 28 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.List; 32 import java.util.Set; 33 import 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 44 public 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 */ onStateChanged(RemoteConnection connection, int state)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 */ onDisconnected( RemoteConnection connection, DisconnectCause disconnectCause)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 */ onRingbackRequested(RemoteConnection connection, boolean ringback)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 */ onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities)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 */ onPostDialWait(RemoteConnection connection, String remainingPostDialSequence)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 */ onVoipAudioChanged(RemoteConnection connection, boolean isVoip)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 */ onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints)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 */ onAddressChanged(RemoteConnection connection, Uri address, int presentation)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 */ onCallerDisplayNameChanged( RemoteConnection connection, String callerDisplayName, int presentation)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 */ onVideoStateChanged(RemoteConnection connection, int videoState)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 */ onDestroyed(RemoteConnection connection)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 */ onConferenceableConnectionsChanged( RemoteConnection connection, List<RemoteConnection> conferenceableConnections)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 */ onVideoProviderChanged( RemoteConnection connection, VideoProvider videoProvider)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 */ onConferenceChanged( RemoteConnection connection, RemoteConference conference)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 { onReceiveSessionModifyRequest( VideoProvider videoProvider, VideoProfile videoProfile)196 public void onReceiveSessionModifyRequest( 197 VideoProvider videoProvider, 198 VideoProfile videoProfile) {} 199 onReceiveSessionModifyResponse( VideoProvider videoProvider, int status, VideoProfile requestedProfile, VideoProfile responseProfile)200 public void onReceiveSessionModifyResponse( 201 VideoProvider videoProvider, 202 int status, 203 VideoProfile requestedProfile, 204 VideoProfile responseProfile) {} 205 onHandleCallSessionEvent(VideoProvider videoProvider, int event)206 public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {} 207 onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height)208 public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {} 209 onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage)210 public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {} 211 onCameraCapabilitiesChanged( VideoProvider videoProvider, CameraCapabilities cameraCapabilities)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 VideoProvider(IVideoProvider videoProviderBinder)284 public VideoProvider(IVideoProvider videoProviderBinder) { 285 mVideoProviderBinder = videoProviderBinder; 286 try { 287 mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder()); 288 } catch (RemoteException e) { 289 } 290 } 291 addListener(Listener l)292 public void addListener(Listener l) { 293 mListeners.add(l); 294 } 295 removeListener(Listener l)296 public void removeListener(Listener l) { 297 mListeners.remove(l); 298 } 299 setCamera(String cameraId)300 public void setCamera(String cameraId) { 301 try { 302 mVideoProviderBinder.setCamera(cameraId); 303 } catch (RemoteException e) { 304 } 305 } 306 setPreviewSurface(Surface surface)307 public void setPreviewSurface(Surface surface) { 308 try { 309 mVideoProviderBinder.setPreviewSurface(surface); 310 } catch (RemoteException e) { 311 } 312 } 313 setDisplaySurface(Surface surface)314 public void setDisplaySurface(Surface surface) { 315 try { 316 mVideoProviderBinder.setDisplaySurface(surface); 317 } catch (RemoteException e) { 318 } 319 } 320 setDeviceOrientation(int rotation)321 public void setDeviceOrientation(int rotation) { 322 try { 323 mVideoProviderBinder.setDeviceOrientation(rotation); 324 } catch (RemoteException e) { 325 } 326 } 327 setZoom(float value)328 public void setZoom(float value) { 329 try { 330 mVideoProviderBinder.setZoom(value); 331 } catch (RemoteException e) { 332 } 333 } 334 sendSessionModifyRequest(VideoProfile reqProfile)335 public void sendSessionModifyRequest(VideoProfile reqProfile) { 336 try { 337 mVideoProviderBinder.sendSessionModifyRequest(reqProfile); 338 } catch (RemoteException e) { 339 } 340 } 341 sendSessionModifyResponse(VideoProfile responseProfile)342 public void sendSessionModifyResponse(VideoProfile responseProfile) { 343 try { 344 mVideoProviderBinder.sendSessionModifyResponse(responseProfile); 345 } catch (RemoteException e) { 346 } 347 } 348 requestCameraCapabilities()349 public void requestCameraCapabilities() { 350 try { 351 mVideoProviderBinder.requestCameraCapabilities(); 352 } catch (RemoteException e) { 353 } 354 } 355 requestCallDataUsage()356 public void requestCallDataUsage() { 357 try { 358 mVideoProviderBinder.requestCallDataUsage(); 359 } catch (RemoteException e) { 360 } 361 } 362 setPauseImage(String uri)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 */ RemoteConnection( String id, IConnectionService connectionService, ConnectionRequest request)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 * Create a RemoteConnection which is used for failed connections. Note that using it for any 414 * "real" purpose will almost certainly fail. Callers should note the failure and act 415 * accordingly (moving on to another RemoteConnection, for example) 416 * 417 * @param disconnectCause The reason for the failed connection. 418 * @hide 419 */ RemoteConnection(DisconnectCause disconnectCause)420 RemoteConnection(DisconnectCause disconnectCause) { 421 this("NULL", null, null); 422 mConnected = false; 423 mState = Connection.STATE_DISCONNECTED; 424 mDisconnectCause = disconnectCause; 425 } 426 427 /** 428 * Adds a callback to this {@code RemoteConnection}. 429 * 430 * @param callback A {@code Callback}. 431 */ registerCallback(Callback callback)432 public void registerCallback(Callback callback) { 433 mCallbacks.add(callback); 434 } 435 436 /** 437 * Removes a callback from this {@code RemoteConnection}. 438 * 439 * @param callback A {@code Callback}. 440 */ unregisterCallback(Callback callback)441 public void unregisterCallback(Callback callback) { 442 if (callback != null) { 443 mCallbacks.remove(callback); 444 } 445 } 446 447 /** 448 * Obtains the state of this {@code RemoteConnection}. 449 * 450 * @return A state value, chosen from the {@code STATE_*} constants. 451 */ getState()452 public int getState() { 453 return mState; 454 } 455 456 /** 457 * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the 458 * disconnect cause expressed as a code chosen from among those declared in 459 * {@link DisconnectCause}. 460 */ getDisconnectCause()461 public DisconnectCause getDisconnectCause() { 462 return mDisconnectCause; 463 } 464 465 /** 466 * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in 467 * {@link PhoneCapabilities}. 468 */ getCallCapabilities()469 public int getCallCapabilities() { 470 return mCallCapabilities; 471 } 472 473 /** 474 * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP. 475 */ isVoipAudioMode()476 public boolean isVoipAudioMode() { 477 return mIsVoipAudioMode; 478 } 479 480 /** 481 * @return The current {@link StatusHints} of this {@code RemoteConnection}, 482 * or {@code null} if none have been set. 483 */ getStatusHints()484 public StatusHints getStatusHints() { 485 return mStatusHints; 486 } 487 488 /** 489 * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently 490 * connected. 491 */ getAddress()492 public Uri getAddress() { 493 return mAddress; 494 } 495 496 /** 497 * @return The presentation requirements for the address. See {@link TelecomManager} for valid 498 * values. 499 */ getAddressPresentation()500 public int getAddressPresentation() { 501 return mAddressPresentation; 502 } 503 504 /** 505 * @return The display name for the caller. 506 */ getCallerDisplayName()507 public CharSequence getCallerDisplayName() { 508 return mCallerDisplayName; 509 } 510 511 /** 512 * @return The presentation requirements for the caller display name. See 513 * {@link TelecomManager} for valid values. 514 */ getCallerDisplayNamePresentation()515 public int getCallerDisplayNamePresentation() { 516 return mCallerDisplayNamePresentation; 517 } 518 519 /** 520 * @return The video state of the {@code RemoteConnection}. See 521 * {@link VideoProfile.VideoState}. 522 * @hide 523 */ getVideoState()524 public int getVideoState() { 525 return mVideoState; 526 } 527 528 /** 529 * @return The video provider associated with this {@code RemoteConnection}. 530 * @hide 531 */ getVideoProvider()532 public final VideoProvider getVideoProvider() { 533 return mVideoProvider; 534 } 535 536 /** 537 * @return Whether the {@code RemoteConnection} is requesting that the framework play a 538 * ringback tone on its behalf. 539 */ isRingbackRequested()540 public boolean isRingbackRequested() { 541 return false; 542 } 543 544 /** 545 * Instructs this {@code RemoteConnection} to abort. 546 */ abort()547 public void abort() { 548 try { 549 if (mConnected) { 550 mConnectionService.abort(mConnectionId); 551 } 552 } catch (RemoteException ignored) { 553 } 554 } 555 556 /** 557 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. 558 */ answer()559 public void answer() { 560 try { 561 if (mConnected) { 562 mConnectionService.answer(mConnectionId); 563 } 564 } catch (RemoteException ignored) { 565 } 566 } 567 568 /** 569 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. 570 * @param videoState The video state in which to answer the call. 571 * @hide 572 */ answer(int videoState)573 public void answer(int videoState) { 574 try { 575 if (mConnected) { 576 mConnectionService.answerVideo(mConnectionId, videoState); 577 } 578 } catch (RemoteException ignored) { 579 } 580 } 581 582 /** 583 * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject. 584 */ reject()585 public void reject() { 586 try { 587 if (mConnected) { 588 mConnectionService.reject(mConnectionId); 589 } 590 } catch (RemoteException ignored) { 591 } 592 } 593 594 /** 595 * Instructs this {@code RemoteConnection} to go on hold. 596 */ hold()597 public void hold() { 598 try { 599 if (mConnected) { 600 mConnectionService.hold(mConnectionId); 601 } 602 } catch (RemoteException ignored) { 603 } 604 } 605 606 /** 607 * Instructs this {@link Connection#STATE_HOLDING} call to release from hold. 608 */ unhold()609 public void unhold() { 610 try { 611 if (mConnected) { 612 mConnectionService.unhold(mConnectionId); 613 } 614 } catch (RemoteException ignored) { 615 } 616 } 617 618 /** 619 * Instructs this {@code RemoteConnection} to disconnect. 620 */ disconnect()621 public void disconnect() { 622 try { 623 if (mConnected) { 624 mConnectionService.disconnect(mConnectionId); 625 } 626 } catch (RemoteException ignored) { 627 } 628 } 629 630 /** 631 * Instructs this {@code RemoteConnection} to play a dual-tone multi-frequency signaling 632 * (DTMF) tone. 633 * 634 * Any other currently playing DTMF tone in the specified call is immediately stopped. 635 * 636 * @param digit A character representing the DTMF digit for which to play the tone. This 637 * value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}. 638 */ playDtmfTone(char digit)639 public void playDtmfTone(char digit) { 640 try { 641 if (mConnected) { 642 mConnectionService.playDtmfTone(mConnectionId, digit); 643 } 644 } catch (RemoteException ignored) { 645 } 646 } 647 648 /** 649 * Instructs this {@code RemoteConnection} to stop any dual-tone multi-frequency signaling 650 * (DTMF) tone currently playing. 651 * 652 * DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is 653 * currently playing, this method will do nothing. 654 */ stopDtmfTone()655 public void stopDtmfTone() { 656 try { 657 if (mConnected) { 658 mConnectionService.stopDtmfTone(mConnectionId); 659 } 660 } catch (RemoteException ignored) { 661 } 662 } 663 664 /** 665 * Instructs this {@code RemoteConnection} to continue playing a post-dial DTMF string. 666 * 667 * A post-dial DTMF string is a string of digits following the first instance of either 668 * {@link TelecomManager#DTMF_CHARACTER_WAIT} or {@link TelecomManager#DTMF_CHARACTER_PAUSE}. 669 * These digits are immediately sent as DTMF tones to the recipient as soon as the 670 * connection is made. 671 * 672 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this 673 * {@code RemoteConnection} will temporarily pause playing the tones for a pre-defined period 674 * of time. 675 * 676 * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this 677 * {@code RemoteConnection} will pause playing the tones and notify callbackss via 678 * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app 679 * should display to the user an indication of this state and an affordance to continue 680 * the postdial sequence. When the user decides to continue the postdial sequence, the in-call 681 * app should invoke the {@link #postDialContinue(boolean)} method. 682 * 683 * @param proceed Whether or not to continue with the post-dial sequence. 684 */ postDialContinue(boolean proceed)685 public void postDialContinue(boolean proceed) { 686 try { 687 if (mConnected) { 688 mConnectionService.onPostDialContinue(mConnectionId, proceed); 689 } 690 } catch (RemoteException ignored) { 691 } 692 } 693 694 /** 695 * Set the audio state of this {@code RemoteConnection}. 696 * 697 * @param state The audio state of this {@code RemoteConnection}. 698 */ setAudioState(AudioState state)699 public void setAudioState(AudioState state) { 700 try { 701 if (mConnected) { 702 mConnectionService.onAudioStateChanged(mConnectionId, state); 703 } 704 } catch (RemoteException ignored) { 705 } 706 } 707 708 /** 709 * Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be 710 * successfully asked to create a conference with. 711 * 712 * @return The {@code RemoteConnection}s with which this {@code RemoteConnection} may be 713 * merged into a {@link RemoteConference}. 714 */ getConferenceableConnections()715 public List<RemoteConnection> getConferenceableConnections() { 716 return mUnmodifiableconferenceableConnections; 717 } 718 719 /** 720 * Obtain the {@code RemoteConference} that this {@code RemoteConnection} may be a part 721 * of, or {@code null} if there is no such {@code RemoteConference}. 722 * 723 * @return A {@code RemoteConference} or {@code null}; 724 */ getConference()725 public RemoteConference getConference() { 726 return mConference; 727 } 728 729 /** {@hide} */ getId()730 String getId() { 731 return mConnectionId; 732 } 733 734 /** {@hide} */ getConnectionService()735 IConnectionService getConnectionService() { 736 return mConnectionService; 737 } 738 739 /** 740 * @hide 741 */ setState(int state)742 void setState(int state) { 743 if (mState != state) { 744 mState = state; 745 for (Callback c: mCallbacks) { 746 c.onStateChanged(this, state); 747 } 748 } 749 } 750 751 /** 752 * @hide 753 */ setDisconnected(DisconnectCause disconnectCause)754 void setDisconnected(DisconnectCause disconnectCause) { 755 if (mState != Connection.STATE_DISCONNECTED) { 756 mState = Connection.STATE_DISCONNECTED; 757 mDisconnectCause = disconnectCause; 758 759 for (Callback c : mCallbacks) { 760 c.onDisconnected(this, mDisconnectCause); 761 } 762 } 763 } 764 765 /** 766 * @hide 767 */ setRingbackRequested(boolean ringback)768 void setRingbackRequested(boolean ringback) { 769 if (mRingbackRequested != ringback) { 770 mRingbackRequested = ringback; 771 for (Callback c : mCallbacks) { 772 c.onRingbackRequested(this, ringback); 773 } 774 } 775 } 776 777 /** 778 * @hide 779 */ setCallCapabilities(int callCapabilities)780 void setCallCapabilities(int callCapabilities) { 781 mCallCapabilities = callCapabilities; 782 for (Callback c : mCallbacks) { 783 c.onCallCapabilitiesChanged(this, callCapabilities); 784 } 785 } 786 787 /** 788 * @hide 789 */ setDestroyed()790 void setDestroyed() { 791 if (!mCallbacks.isEmpty()) { 792 // Make sure that the callbacks are notified that the call is destroyed first. 793 if (mState != Connection.STATE_DISCONNECTED) { 794 setDisconnected( 795 new DisconnectCause(DisconnectCause.ERROR, "Connection destroyed.")); 796 } 797 798 for (Callback c : mCallbacks) { 799 c.onDestroyed(this); 800 } 801 mCallbacks.clear(); 802 803 mConnected = false; 804 } 805 } 806 807 /** 808 * @hide 809 */ setPostDialWait(String remainingDigits)810 void setPostDialWait(String remainingDigits) { 811 for (Callback c : mCallbacks) { 812 c.onPostDialWait(this, remainingDigits); 813 } 814 } 815 816 /** 817 * @hide 818 */ setVideoState(int videoState)819 void setVideoState(int videoState) { 820 mVideoState = videoState; 821 for (Callback c : mCallbacks) { 822 c.onVideoStateChanged(this, videoState); 823 } 824 } 825 826 /** 827 * @hide 828 */ setVideoProvider(VideoProvider videoProvider)829 void setVideoProvider(VideoProvider videoProvider) { 830 mVideoProvider = videoProvider; 831 for (Callback c : mCallbacks) { 832 c.onVideoProviderChanged(this, videoProvider); 833 } 834 } 835 836 /** @hide */ setIsVoipAudioMode(boolean isVoip)837 void setIsVoipAudioMode(boolean isVoip) { 838 mIsVoipAudioMode = isVoip; 839 for (Callback c : mCallbacks) { 840 c.onVoipAudioChanged(this, isVoip); 841 } 842 } 843 844 /** @hide */ setStatusHints(StatusHints statusHints)845 void setStatusHints(StatusHints statusHints) { 846 mStatusHints = statusHints; 847 for (Callback c : mCallbacks) { 848 c.onStatusHintsChanged(this, statusHints); 849 } 850 } 851 852 /** @hide */ setAddress(Uri address, int presentation)853 void setAddress(Uri address, int presentation) { 854 mAddress = address; 855 mAddressPresentation = presentation; 856 for (Callback c : mCallbacks) { 857 c.onAddressChanged(this, address, presentation); 858 } 859 } 860 861 /** @hide */ setCallerDisplayName(String callerDisplayName, int presentation)862 void setCallerDisplayName(String callerDisplayName, int presentation) { 863 mCallerDisplayName = callerDisplayName; 864 mCallerDisplayNamePresentation = presentation; 865 for (Callback c : mCallbacks) { 866 c.onCallerDisplayNameChanged(this, callerDisplayName, presentation); 867 } 868 } 869 870 /** @hide */ setConferenceableConnections(List<RemoteConnection> conferenceableConnections)871 void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) { 872 mConferenceableConnections.clear(); 873 mConferenceableConnections.addAll(conferenceableConnections); 874 for (Callback c : mCallbacks) { 875 c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections); 876 } 877 } 878 879 /** @hide */ setConference(RemoteConference conference)880 void setConference(RemoteConference conference) { 881 if (mConference != conference) { 882 mConference = conference; 883 for (Callback c : mCallbacks) { 884 c.onConferenceChanged(this, conference); 885 } 886 } 887 } 888 889 /** 890 * Create a RemoteConnection represents a failure, and which will be in 891 * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost 892 * certainly result in bad things happening. Do not do this. 893 * 894 * @return a failed {@link RemoteConnection} 895 * 896 * @hide 897 */ failure(DisconnectCause disconnectCause)898 public static RemoteConnection failure(DisconnectCause disconnectCause) { 899 return new RemoteConnection(disconnectCause); 900 } 901 } 902