1 /* 2 * Copyright (C) 2006 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 com.android.internal.telephony; 18 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.os.SystemClock; 22 import android.telecom.ConferenceParticipant; 23 import android.telephony.DisconnectCause; 24 import android.telephony.Rlog; 25 import android.util.Log; 26 27 import java.lang.Override; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Set; 31 import java.util.concurrent.CopyOnWriteArraySet; 32 33 /** 34 * {@hide} 35 */ 36 public abstract class Connection { 37 38 public interface PostDialListener { onPostDialWait()39 void onPostDialWait(); onPostDialChar(char c)40 void onPostDialChar(char c); 41 } 42 43 /** 44 * Capabilities that will be mapped to telecom connection 45 * capabilities. 46 */ 47 public static class Capability { 48 49 /** 50 * For an IMS video call, indicates that the local side of the call supports downgrading 51 * from a video call to an audio-only call. 52 */ 53 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL = 0x00000001; 54 55 /** 56 * For an IMS video call, indicates that the peer supports downgrading to an audio-only 57 * call. 58 */ 59 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE = 0x00000002; 60 61 /** 62 * For an IMS call, indicates that the call supports video locally. 63 */ 64 public static final int SUPPORTS_VT_LOCAL_BIDIRECTIONAL = 0x00000004; 65 66 /** 67 * For an IMS call, indicates that the peer supports video. 68 */ 69 public static final int SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 0x00000008; 70 71 /** 72 * Indicates that the connection is an external connection (e.g. an instance of the class 73 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection}. 74 */ 75 public static final int IS_EXTERNAL_CONNECTION = 0x00000010; 76 77 /** 78 * Indicates that this external connection can be pulled from the remote device to the 79 * local device. 80 */ 81 public static final int IS_PULLABLE = 0x00000020; 82 } 83 84 /** 85 * Listener interface for events related to the connection which should be reported to the 86 * {@link android.telecom.Connection}. 87 */ 88 public interface Listener { onVideoStateChanged(int videoState)89 public void onVideoStateChanged(int videoState); onConnectionCapabilitiesChanged(int capability)90 public void onConnectionCapabilitiesChanged(int capability); onWifiChanged(boolean isWifi)91 public void onWifiChanged(boolean isWifi); onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)92 public void onVideoProviderChanged( 93 android.telecom.Connection.VideoProvider videoProvider); onAudioQualityChanged(int audioQuality)94 public void onAudioQualityChanged(int audioQuality); onConferenceParticipantsChanged(List<ConferenceParticipant> participants)95 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants); onCallSubstateChanged(int callSubstate)96 public void onCallSubstateChanged(int callSubstate); onMultipartyStateChanged(boolean isMultiParty)97 public void onMultipartyStateChanged(boolean isMultiParty); onConferenceMergedFailed()98 public void onConferenceMergedFailed(); onExtrasChanged(Bundle extras)99 public void onExtrasChanged(Bundle extras); onExitedEcmMode()100 public void onExitedEcmMode(); onCallPullFailed(Connection externalConnection)101 public void onCallPullFailed(Connection externalConnection); onHandoverToWifiFailed()102 public void onHandoverToWifiFailed(); onConnectionEvent(String event, Bundle extras)103 public void onConnectionEvent(String event, Bundle extras); 104 } 105 106 /** 107 * Base listener implementation. 108 */ 109 public abstract static class ListenerBase implements Listener { 110 @Override onVideoStateChanged(int videoState)111 public void onVideoStateChanged(int videoState) {} 112 @Override onConnectionCapabilitiesChanged(int capability)113 public void onConnectionCapabilitiesChanged(int capability) {} 114 @Override onWifiChanged(boolean isWifi)115 public void onWifiChanged(boolean isWifi) {} 116 @Override onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)117 public void onVideoProviderChanged( 118 android.telecom.Connection.VideoProvider videoProvider) {} 119 @Override onAudioQualityChanged(int audioQuality)120 public void onAudioQualityChanged(int audioQuality) {} 121 @Override onConferenceParticipantsChanged(List<ConferenceParticipant> participants)122 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {} 123 @Override onCallSubstateChanged(int callSubstate)124 public void onCallSubstateChanged(int callSubstate) {} 125 @Override onMultipartyStateChanged(boolean isMultiParty)126 public void onMultipartyStateChanged(boolean isMultiParty) {} 127 @Override onConferenceMergedFailed()128 public void onConferenceMergedFailed() {} 129 @Override onExtrasChanged(Bundle extras)130 public void onExtrasChanged(Bundle extras) {} 131 @Override onExitedEcmMode()132 public void onExitedEcmMode() {} 133 @Override onCallPullFailed(Connection externalConnection)134 public void onCallPullFailed(Connection externalConnection) {} 135 @Override onHandoverToWifiFailed()136 public void onHandoverToWifiFailed() {} 137 @Override onConnectionEvent(String event, Bundle extras)138 public void onConnectionEvent(String event, Bundle extras) {} 139 } 140 141 public static final int AUDIO_QUALITY_STANDARD = 1; 142 public static final int AUDIO_QUALITY_HIGH_DEFINITION = 2; 143 144 /** 145 * The telecom internal call ID associated with this connection. Only to be used for debugging 146 * purposes. 147 */ 148 private String mTelecomCallId; 149 150 //Caller Name Display 151 protected String mCnapName; 152 protected int mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED; 153 protected String mAddress; // MAY BE NULL!!! 154 protected String mDialString; // outgoing calls only 155 protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED; 156 protected boolean mIsIncoming; 157 /* 158 * These time/timespan values are based on System.currentTimeMillis(), 159 * i.e., "wall clock" time. 160 */ 161 protected long mCreateTime; 162 protected long mConnectTime; 163 /* 164 * These time/timespan values are based on SystemClock.elapsedRealTime(), 165 * i.e., time since boot. They are appropriate for comparison and 166 * calculating deltas. 167 */ 168 protected long mConnectTimeReal; 169 protected long mDuration; 170 protected long mHoldingStartTime; // The time when the Connection last transitioned 171 // into HOLDING 172 protected Connection mOrigConnection; 173 private List<PostDialListener> mPostDialListeners = new ArrayList<>(); 174 public Set<Listener> mListeners = new CopyOnWriteArraySet<>(); 175 176 protected boolean mNumberConverted = false; 177 protected String mConvertedNumber; 178 179 protected String mPostDialString; // outgoing calls only 180 protected int mNextPostDialChar; // index into postDialString 181 182 protected int mCause = DisconnectCause.NOT_DISCONNECTED; 183 protected PostDialState mPostDialState = PostDialState.NOT_STARTED; 184 185 private static String LOG_TAG = "Connection"; 186 187 Object mUserData; 188 private int mVideoState; 189 private int mConnectionCapabilities; 190 private boolean mIsWifi; 191 private boolean mAudioModeIsVoip; 192 private int mAudioQuality; 193 private int mCallSubstate; 194 private android.telecom.Connection.VideoProvider mVideoProvider; 195 public Call.State mPreHandoverState = Call.State.IDLE; 196 private Bundle mExtras; 197 private int mPhoneType; 198 private boolean mAnsweringDisconnectsActiveCall; 199 private boolean mAllowAddCallDuringVideoCall; 200 201 /** 202 * Used to indicate that this originated from pulling a {@link android.telecom.Connection} with 203 * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL}. 204 */ 205 private boolean mIsPulledCall = false; 206 207 /** 208 * Where {@link #mIsPulledCall} is {@code true}, contains the dialog Id of the external call 209 * which is being pulled (e.g. 210 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection#getCallId()}). 211 */ 212 private int mPulledDialogId; 213 Connection(int phoneType)214 protected Connection(int phoneType) { 215 mPhoneType = phoneType; 216 } 217 218 /* Instance Methods */ 219 220 /** 221 * @return The telecom internal call ID associated with this connection. Only to be used for 222 * debugging purposes. 223 */ getTelecomCallId()224 public String getTelecomCallId() { 225 return mTelecomCallId; 226 } 227 228 /** 229 * Sets the telecom call ID associated with this connection. 230 * 231 * @param telecomCallId The telecom call ID. 232 */ setTelecomCallId(String telecomCallId)233 public void setTelecomCallId(String telecomCallId) { 234 mTelecomCallId = telecomCallId; 235 } 236 237 /** 238 * Gets address (e.g. phone number) associated with connection. 239 * TODO: distinguish reasons for unavailability 240 * 241 * @return address or null if unavailable 242 */ 243 getAddress()244 public String getAddress() { 245 return mAddress; 246 } 247 248 /** 249 * Gets CNAP name associated with connection. 250 * @return cnap name or null if unavailable 251 */ getCnapName()252 public String getCnapName() { 253 return mCnapName; 254 } 255 256 /** 257 * Get original dial string. 258 * @return original dial string or null if unavailable 259 */ getOrigDialString()260 public String getOrigDialString(){ 261 return null; 262 } 263 264 /** 265 * Gets CNAP presentation associated with connection. 266 * @return cnap name or null if unavailable 267 */ 268 getCnapNamePresentation()269 public int getCnapNamePresentation() { 270 return mCnapNamePresentation; 271 } 272 273 /** 274 * @return Call that owns this Connection, or null if none 275 */ getCall()276 public abstract Call getCall(); 277 278 /** 279 * Connection create time in currentTimeMillis() format 280 * Basically, set when object is created. 281 * Effectively, when an incoming call starts ringing or an 282 * outgoing call starts dialing 283 */ getCreateTime()284 public long getCreateTime() { 285 return mCreateTime; 286 } 287 288 /** 289 * Connection connect time in currentTimeMillis() format. 290 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 291 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 292 * Returns 0 before then. 293 */ getConnectTime()294 public long getConnectTime() { 295 return mConnectTime; 296 } 297 298 /** 299 * Sets the Connection connect time in currentTimeMillis() format. 300 * 301 * @param connectTime the new connect time. 302 */ setConnectTime(long connectTime)303 public void setConnectTime(long connectTime) { 304 mConnectTime = connectTime; 305 } 306 307 /** 308 * Connection connect time in elapsedRealtime() format. 309 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 310 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 311 * Returns 0 before then. 312 */ getConnectTimeReal()313 public long getConnectTimeReal() { 314 return mConnectTimeReal; 315 } 316 317 /** 318 * Disconnect time in currentTimeMillis() format. 319 * The time when this Connection makes a transition into ENDED or FAIL. 320 * Returns 0 before then. 321 */ getDisconnectTime()322 public abstract long getDisconnectTime(); 323 324 /** 325 * Returns the number of milliseconds the call has been connected, 326 * or 0 if the call has never connected. 327 * If the call is still connected, then returns the elapsed 328 * time since connect. 329 */ getDurationMillis()330 public long getDurationMillis() { 331 if (mConnectTimeReal == 0) { 332 return 0; 333 } else if (mDuration == 0) { 334 return SystemClock.elapsedRealtime() - mConnectTimeReal; 335 } else { 336 return mDuration; 337 } 338 } 339 340 /** 341 * The time when this Connection last transitioned into HOLDING 342 * in elapsedRealtime() format. 343 * Returns 0, if it has never made a transition into HOLDING. 344 */ getHoldingStartTime()345 public long getHoldingStartTime() { 346 return mHoldingStartTime; 347 } 348 349 /** 350 * If this connection is HOLDING, return the number of milliseconds 351 * that it has been on hold for (approximately). 352 * If this connection is in any other state, return 0. 353 */ 354 getHoldDurationMillis()355 public abstract long getHoldDurationMillis(); 356 357 /** 358 * Returns call disconnect cause. Values are defined in 359 * {@link android.telephony.DisconnectCause}. If the call is not yet 360 * disconnected, NOT_DISCONNECTED is returned. 361 */ getDisconnectCause()362 public int getDisconnectCause() { 363 return mCause; 364 } 365 366 /** 367 * Returns a string disconnect cause which is from vendor. 368 * Vendors may use this string to explain the underline causes of failed calls. 369 * There is no guarantee that it is non-null nor it'll have meaningful stable values. 370 * Only use it when getDisconnectCause() returns a value that is not specific enough, like 371 * ERROR_UNSPECIFIED. 372 */ getVendorDisconnectCause()373 public abstract String getVendorDisconnectCause(); 374 375 /** 376 * Returns true of this connection originated elsewhere 377 * ("MT" or mobile terminated; another party called this terminal) 378 * or false if this call originated here (MO or mobile originated). 379 */ isIncoming()380 public boolean isIncoming() { 381 return mIsIncoming; 382 } 383 384 /** 385 * If this Connection is connected, then it is associated with 386 * a Call. 387 * 388 * Returns getCall().getState() or Call.State.IDLE if not 389 * connected 390 */ getState()391 public Call.State getState() { 392 Call c; 393 394 c = getCall(); 395 396 if (c == null) { 397 return Call.State.IDLE; 398 } else { 399 return c.getState(); 400 } 401 } 402 403 /** 404 * If this connection went through handover return the state of the 405 * call that contained this connection before handover. 406 */ getStateBeforeHandover()407 public Call.State getStateBeforeHandover() { 408 return mPreHandoverState; 409 } 410 411 /** 412 * Get the details of conference participants. Expected to be 413 * overwritten by the Connection subclasses. 414 */ getConferenceParticipants()415 public List<ConferenceParticipant> getConferenceParticipants() { 416 Call c; 417 418 c = getCall(); 419 420 if (c == null) { 421 return null; 422 } else { 423 return c.getConferenceParticipants(); 424 } 425 } 426 427 /** 428 * isAlive() 429 * 430 * @return true if the connection isn't disconnected 431 * (could be active, holding, ringing, dialing, etc) 432 */ 433 public boolean isAlive()434 isAlive() { 435 return getState().isAlive(); 436 } 437 438 /** 439 * Returns true if Connection is connected and is INCOMING or WAITING 440 */ 441 public boolean isRinging()442 isRinging() { 443 return getState().isRinging(); 444 } 445 446 /** 447 * 448 * @return the userdata set in setUserData() 449 */ getUserData()450 public Object getUserData() { 451 return mUserData; 452 } 453 454 /** 455 * 456 * @param userdata user can store an any userdata in the Connection object. 457 */ setUserData(Object userdata)458 public void setUserData(Object userdata) { 459 mUserData = userdata; 460 } 461 462 /** 463 * Hangup individual Connection 464 */ hangup()465 public abstract void hangup() throws CallStateException; 466 467 /** 468 * Separate this call from its owner Call and assigns it to a new Call 469 * (eg if it is currently part of a Conference call 470 * TODO: Throw exception? Does GSM require error display on failure here? 471 */ separate()472 public abstract void separate() throws CallStateException; 473 474 public enum PostDialState { 475 NOT_STARTED, /* The post dial string playback hasn't 476 been started, or this call is not yet 477 connected, or this is an incoming call */ 478 STARTED, /* The post dial string playback has begun */ 479 WAIT, /* The post dial string playback is waiting for a 480 call to proceedAfterWaitChar() */ 481 WILD, /* The post dial string playback is waiting for a 482 call to proceedAfterWildChar() */ 483 COMPLETE, /* The post dial string playback is complete */ 484 CANCELLED, /* The post dial string playback was cancelled 485 with cancelPostDial() */ 486 PAUSE /* The post dial string playback is pausing for a 487 call to processNextPostDialChar*/ 488 } 489 clearUserData()490 public void clearUserData(){ 491 mUserData = null; 492 } 493 addPostDialListener(PostDialListener listener)494 public final void addPostDialListener(PostDialListener listener) { 495 if (!mPostDialListeners.contains(listener)) { 496 mPostDialListeners.add(listener); 497 } 498 } 499 removePostDialListener(PostDialListener listener)500 public final void removePostDialListener(PostDialListener listener) { 501 mPostDialListeners.remove(listener); 502 } 503 clearPostDialListeners()504 protected final void clearPostDialListeners() { 505 if (mPostDialListeners != null) { 506 mPostDialListeners.clear(); 507 } 508 } 509 notifyPostDialListeners()510 protected final void notifyPostDialListeners() { 511 if (getPostDialState() == PostDialState.WAIT) { 512 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 513 listener.onPostDialWait(); 514 } 515 } 516 } 517 notifyPostDialListenersNextChar(char c)518 protected final void notifyPostDialListenersNextChar(char c) { 519 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 520 listener.onPostDialChar(c); 521 } 522 } 523 getPostDialState()524 public PostDialState getPostDialState() { 525 return mPostDialState; 526 } 527 528 /** 529 * Returns the portion of the post dial string that has not 530 * yet been dialed, or "" if none 531 */ getRemainingPostDialString()532 public String getRemainingPostDialString() { 533 if (mPostDialState == PostDialState.CANCELLED 534 || mPostDialState == PostDialState.COMPLETE 535 || mPostDialString == null 536 || mPostDialString.length() <= mNextPostDialChar) { 537 return ""; 538 } 539 540 return mPostDialString.substring(mNextPostDialChar); 541 } 542 543 /** 544 * See Phone.setOnPostDialWaitCharacter() 545 */ 546 proceedAfterWaitChar()547 public abstract void proceedAfterWaitChar(); 548 549 /** 550 * See Phone.setOnPostDialWildCharacter() 551 */ proceedAfterWildChar(String str)552 public abstract void proceedAfterWildChar(String str); 553 /** 554 * Cancel any post 555 */ cancelPostDial()556 public abstract void cancelPostDial(); 557 558 /** Called when the connection has been disconnected */ onDisconnect(int cause)559 public boolean onDisconnect(int cause) { 560 return false; 561 } 562 563 /** 564 * Returns the caller id presentation type for incoming and waiting calls 565 * @return one of PRESENTATION_* 566 */ getNumberPresentation()567 public abstract int getNumberPresentation(); 568 569 /** 570 * Returns the User to User Signaling (UUS) information associated with 571 * incoming and waiting calls 572 * @return UUSInfo containing the UUS userdata. 573 */ getUUSInfo()574 public abstract UUSInfo getUUSInfo(); 575 576 /** 577 * Returns the CallFail reason provided by the RIL with the result of 578 * RIL_REQUEST_LAST_CALL_FAIL_CAUSE 579 */ getPreciseDisconnectCause()580 public abstract int getPreciseDisconnectCause(); 581 582 /** 583 * Returns the original Connection instance associated with 584 * this Connection 585 */ getOrigConnection()586 public Connection getOrigConnection() { 587 return mOrigConnection; 588 } 589 590 /** 591 * Returns whether the original ImsPhoneConnection was a member 592 * of a conference call 593 * @return valid only when getOrigConnection() is not null 594 */ isMultiparty()595 public abstract boolean isMultiparty(); 596 597 /** 598 * Applicable only for IMS Call. Determines if this call is the origin of the conference call 599 * (i.e. {@code #isConferenceHost()} is {@code true}), or if it is a member of a conference 600 * hosted on another device. 601 * 602 * @return {@code true} if this call is the origin of the conference call it is a member of, 603 * {@code false} otherwise. 604 */ isConferenceHost()605 public boolean isConferenceHost() { 606 return false; 607 } 608 609 /** 610 * Applicable only for IMS Call. Determines if a connection is a member of a conference hosted 611 * on another device. 612 * 613 * @return {@code true} if the connection is a member of a conference hosted on another device. 614 */ isMemberOfPeerConference()615 public boolean isMemberOfPeerConference() { 616 return false; 617 } 618 migrateFrom(Connection c)619 public void migrateFrom(Connection c) { 620 if (c == null) return; 621 mListeners = c.mListeners; 622 mDialString = c.getOrigDialString(); 623 mCreateTime = c.getCreateTime(); 624 mConnectTime = c.getConnectTime(); 625 mConnectTimeReal = c.getConnectTimeReal(); 626 mHoldingStartTime = c.getHoldingStartTime(); 627 mOrigConnection = c.getOrigConnection(); 628 mPostDialString = c.mPostDialString; 629 mNextPostDialChar = c.mNextPostDialChar; 630 } 631 632 /** 633 * Assign a listener to be notified of state changes. 634 * 635 * @param listener A listener. 636 */ addListener(Listener listener)637 public final void addListener(Listener listener) { 638 mListeners.add(listener); 639 } 640 641 /** 642 * Removes a listener. 643 * 644 * @param listener A listener. 645 */ removeListener(Listener listener)646 public final void removeListener(Listener listener) { 647 mListeners.remove(listener); 648 } 649 650 /** 651 * Returns the current video state of the connection. 652 * 653 * @return The video state of the connection. 654 */ getVideoState()655 public int getVideoState() { 656 return mVideoState; 657 } 658 659 /** 660 * Called to get Connection capabilities.Returns Capabilities bitmask. 661 * @See Connection.Capability. 662 */ getConnectionCapabilities()663 public int getConnectionCapabilities() { 664 return mConnectionCapabilities; 665 } 666 667 /** 668 * @return {@code} true if the connection has the specified capabilities. 669 */ hasCapabilities(int connectionCapabilities)670 public boolean hasCapabilities(int connectionCapabilities) { 671 return (mConnectionCapabilities & connectionCapabilities) == connectionCapabilities; 672 } 673 674 /** 675 * Applies a capability to a capabilities bit-mask. 676 * 677 * @param capabilities The capabilities bit-mask. 678 * @param capability The capability to apply. 679 * @return The capabilities bit-mask with the capability applied. 680 */ addCapability(int capabilities, int capability)681 public static int addCapability(int capabilities, int capability) { 682 return capabilities | capability; 683 } 684 685 /** 686 * Removes a capability to a capabilities bit-mask. 687 * 688 * @param capabilities The capabilities bit-mask. 689 * @param capability The capability to remove. 690 * @return The capabilities bit-mask with the capability removed. 691 */ removeCapability(int capabilities, int capability)692 public static int removeCapability(int capabilities, int capability) { 693 return capabilities & ~capability; 694 } 695 696 /** 697 * Returns whether the connection is using a wifi network. 698 * 699 * @return {@code True} if the connection is using a wifi network. 700 */ isWifi()701 public boolean isWifi() { 702 return mIsWifi; 703 } 704 705 /** 706 * Returns whether the connection uses voip audio mode 707 * 708 * @return {@code True} if the connection uses voip audio mode 709 */ getAudioModeIsVoip()710 public boolean getAudioModeIsVoip() { 711 return mAudioModeIsVoip; 712 } 713 714 /** 715 * Returns the {@link android.telecom.Connection.VideoProvider} for the connection. 716 * 717 * @return The {@link android.telecom.Connection.VideoProvider}. 718 */ getVideoProvider()719 public android.telecom.Connection.VideoProvider getVideoProvider() { 720 return mVideoProvider; 721 } 722 723 /** 724 * Returns the audio-quality for the connection. 725 * 726 * @return The audio quality for the connection. 727 */ getAudioQuality()728 public int getAudioQuality() { 729 return mAudioQuality; 730 } 731 732 733 /** 734 * Returns the current call substate of the connection. 735 * 736 * @return The call substate of the connection. 737 */ getCallSubstate()738 public int getCallSubstate() { 739 return mCallSubstate; 740 } 741 742 743 /** 744 * Sets the videoState for the current connection and reports the changes to all listeners. 745 * Valid video states are defined in {@link android.telecom.VideoProfile}. 746 * 747 * @return The video state. 748 */ setVideoState(int videoState)749 public void setVideoState(int videoState) { 750 mVideoState = videoState; 751 for (Listener l : mListeners) { 752 l.onVideoStateChanged(mVideoState); 753 } 754 } 755 756 /** 757 * Called to set Connection capabilities. This will take Capabilities bitmask as input which is 758 * converted from Capabilities constants. 759 * 760 * @See Connection.Capability. 761 * @param capabilities The Capabilities bitmask. 762 */ setConnectionCapabilities(int capabilities)763 public void setConnectionCapabilities(int capabilities) { 764 if (mConnectionCapabilities != capabilities) { 765 mConnectionCapabilities = capabilities; 766 for (Listener l : mListeners) { 767 l.onConnectionCapabilitiesChanged(mConnectionCapabilities); 768 } 769 } 770 } 771 772 /** 773 * Sets whether a wifi network is used for the connection. 774 * 775 * @param isWifi {@code True} if wifi is being used. 776 */ setWifi(boolean isWifi)777 public void setWifi(boolean isWifi) { 778 mIsWifi = isWifi; 779 for (Listener l : mListeners) { 780 l.onWifiChanged(mIsWifi); 781 } 782 } 783 784 /** 785 * Set the voip audio mode for the connection 786 * 787 * @param isVoip {@code True} if voip audio mode is being used. 788 */ setAudioModeIsVoip(boolean isVoip)789 public void setAudioModeIsVoip(boolean isVoip) { 790 mAudioModeIsVoip = isVoip; 791 } 792 793 /** 794 * Set the audio quality for the connection. 795 * 796 * @param audioQuality The audio quality. 797 */ setAudioQuality(int audioQuality)798 public void setAudioQuality(int audioQuality) { 799 mAudioQuality = audioQuality; 800 for (Listener l : mListeners) { 801 l.onAudioQualityChanged(mAudioQuality); 802 } 803 } 804 805 /** 806 * Notifies listeners that connection extras has changed. 807 * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent 808 * modifications to the extras Bundle do not affect Bundle operations in the onExtrasChanged 809 * listeners. 810 */ setConnectionExtras(Bundle extras)811 public void setConnectionExtras(Bundle extras) { 812 if (extras != null) { 813 mExtras = new Bundle(extras); 814 } else { 815 mExtras = null; 816 } 817 818 for (Listener l : mListeners) { 819 l.onExtrasChanged(mExtras); 820 } 821 } 822 823 /** 824 * Retrieves the current connection extras. 825 * @return the connection extras. 826 */ getConnectionExtras()827 public Bundle getConnectionExtras() { 828 return mExtras == null ? null : new Bundle(mExtras); 829 } 830 831 /** 832 * @return {@code true} if answering the call will cause the current active call to be 833 * disconnected, {@code false} otherwise. 834 */ isActiveCallDisconnectedOnAnswer()835 public boolean isActiveCallDisconnectedOnAnswer() { 836 return mAnsweringDisconnectsActiveCall; 837 } 838 839 /** 840 * Sets whether answering this call will cause the active call to be disconnected. 841 * <p> 842 * Should only be set {@code true} if there is an active call and this call is ringing. 843 * 844 * @param answeringDisconnectsActiveCall {@code true} if answering the call will call the active 845 * call to be disconnected. 846 */ setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall)847 public void setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall) { 848 mAnsweringDisconnectsActiveCall = answeringDisconnectsActiveCall; 849 } 850 shouldAllowAddCallDuringVideoCall()851 public boolean shouldAllowAddCallDuringVideoCall() { 852 return mAllowAddCallDuringVideoCall; 853 } 854 setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall)855 public void setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall) { 856 mAllowAddCallDuringVideoCall = allowAddCallDuringVideoCall; 857 } 858 859 /** 860 * Sets whether the connection is the result of an external call which was pulled to the local 861 * device. 862 * 863 * @param isPulledCall {@code true} if this connection is the result of pulling an external call 864 * to the local device. 865 */ setIsPulledCall(boolean isPulledCall)866 public void setIsPulledCall(boolean isPulledCall) { 867 mIsPulledCall = isPulledCall; 868 } 869 isPulledCall()870 public boolean isPulledCall() { 871 return mIsPulledCall; 872 } 873 874 /** 875 * For an external call which is being pulled (e.g. {@link #isPulledCall()} is {@code true}), 876 * sets the dialog Id for the external call. Used to handle failures to pull a call so that the 877 * pulled call can be reconciled with its original external connection. 878 * 879 * @param pulledDialogId The dialog id associated with a pulled call. 880 */ setPulledDialogId(int pulledDialogId)881 public void setPulledDialogId(int pulledDialogId) { 882 mPulledDialogId = pulledDialogId; 883 } 884 getPulledDialogId()885 public int getPulledDialogId() { 886 return mPulledDialogId; 887 } 888 889 /** 890 * Sets the call substate for the current connection and reports the changes to all listeners. 891 * Valid call substates are defined in {@link android.telecom.Connection}. 892 * 893 * @return The call substate. 894 */ setCallSubstate(int callSubstate)895 public void setCallSubstate(int callSubstate) { 896 mCallSubstate = callSubstate; 897 for (Listener l : mListeners) { 898 l.onCallSubstateChanged(mCallSubstate); 899 } 900 } 901 902 /** 903 * Sets the {@link android.telecom.Connection.VideoProvider} for the connection. 904 * 905 * @param videoProvider The video call provider. 906 */ setVideoProvider(android.telecom.Connection.VideoProvider videoProvider)907 public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 908 mVideoProvider = videoProvider; 909 for (Listener l : mListeners) { 910 l.onVideoProviderChanged(mVideoProvider); 911 } 912 } 913 setConverted(String oriNumber)914 public void setConverted(String oriNumber) { 915 mNumberConverted = true; 916 mConvertedNumber = mAddress; 917 mAddress = oriNumber; 918 mDialString = oriNumber; 919 } 920 921 /** 922 * Notifies listeners of a change to conference participant(s). 923 * 924 * @param conferenceParticipants The participant(s). 925 */ updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants)926 public void updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants) { 927 for (Listener l : mListeners) { 928 l.onConferenceParticipantsChanged(conferenceParticipants); 929 } 930 } 931 932 /** 933 * Notifies listeners of a change to the multiparty state of the connection. 934 * 935 * @param isMultiparty The participant(s). 936 */ updateMultipartyState(boolean isMultiparty)937 public void updateMultipartyState(boolean isMultiparty) { 938 for (Listener l : mListeners) { 939 l.onMultipartyStateChanged(isMultiparty); 940 } 941 } 942 943 /** 944 * Notifies listeners of a failure in merging this connection with the background connection. 945 */ onConferenceMergeFailed()946 public void onConferenceMergeFailed() { 947 for (Listener l : mListeners) { 948 l.onConferenceMergedFailed(); 949 } 950 } 951 952 /** 953 * Notifies that the underlying phone has exited ECM mode. 954 */ onExitedEcmMode()955 public void onExitedEcmMode() { 956 for (Listener l : mListeners) { 957 l.onExitedEcmMode(); 958 } 959 } 960 961 /** 962 * Notifies the connection that a call to {@link #pullExternalCall()} has failed to pull the 963 * call to the local device. 964 * 965 * @param externalConnection The original 966 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection} from which the 967 * pull was initiated. 968 */ onCallPullFailed(Connection externalConnection)969 public void onCallPullFailed(Connection externalConnection) { 970 for (Listener l : mListeners) { 971 l.onCallPullFailed(externalConnection); 972 } 973 } 974 975 /** 976 * Notifies the connection that there was a failure while handing over to WIFI. 977 */ onHandoverToWifiFailed()978 public void onHandoverToWifiFailed() { 979 for (Listener l : mListeners) { 980 l.onHandoverToWifiFailed(); 981 } 982 } 983 984 /** 985 * Notifies the connection of a connection event. 986 */ onConnectionEvent(String event, Bundle extras)987 public void onConnectionEvent(String event, Bundle extras) { 988 for (Listener l : mListeners) { 989 l.onConnectionEvent(event, extras); 990 } 991 } 992 993 /** 994 * Notifies this Connection of a request to disconnect a participant of the conference managed 995 * by the connection. 996 * 997 * @param endpoint the {@link Uri} of the participant to disconnect. 998 */ onDisconnectConferenceParticipant(Uri endpoint)999 public void onDisconnectConferenceParticipant(Uri endpoint) { 1000 } 1001 1002 /** 1003 * Called by a {@link android.telecom.Connection} to indicate that this call should be pulled 1004 * to the local device. 1005 */ pullExternalCall()1006 public void pullExternalCall() { 1007 } 1008 1009 /** 1010 * 1011 */ getPhoneType()1012 public int getPhoneType() { 1013 return mPhoneType; 1014 } 1015 1016 /** 1017 * Build a human representation of a connection instance, suitable for debugging. 1018 * Don't log personal stuff unless in debug mode. 1019 * @return a string representing the internal state of this connection. 1020 */ toString()1021 public String toString() { 1022 StringBuilder str = new StringBuilder(128); 1023 1024 str.append(" callId: " + getTelecomCallId()); 1025 str.append(" isExternal: " + (((mConnectionCapabilities & Capability.IS_EXTERNAL_CONNECTION) 1026 == Capability.IS_EXTERNAL_CONNECTION) ? "Y" : "N")); 1027 if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) { 1028 str.append("addr: " + getAddress()) 1029 .append(" pres.: " + getNumberPresentation()) 1030 .append(" dial: " + getOrigDialString()) 1031 .append(" postdial: " + getRemainingPostDialString()) 1032 .append(" cnap name: " + getCnapName()) 1033 .append("(" + getCnapNamePresentation() + ")"); 1034 } 1035 str.append(" incoming: " + isIncoming()) 1036 .append(" state: " + getState()) 1037 .append(" post dial state: " + getPostDialState()); 1038 return str.toString(); 1039 } 1040 } 1041