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.compat.annotation.UnsupportedAppUsage; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.os.SystemClock; 23 import android.telephony.DisconnectCause; 24 import android.telephony.ServiceState; 25 import android.telephony.ServiceState.RilRadioTechnology; 26 import android.telephony.emergency.EmergencyNumber; 27 import android.util.Log; 28 29 import com.android.ims.internal.ConferenceParticipant; 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 32 import com.android.internal.telephony.util.TelephonyUtils; 33 import com.android.telephony.Rlog; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 import java.util.Set; 38 import java.util.concurrent.CopyOnWriteArraySet; 39 40 /** 41 * {@hide} 42 */ 43 public abstract class Connection { 44 private static final String TAG = "Connection"; 45 46 public static final String ADHOC_CONFERENCE_ADDRESS = "tel:conf-factory"; 47 48 public interface PostDialListener { onPostDialWait()49 void onPostDialWait(); onPostDialChar(char c)50 void onPostDialChar(char c); 51 } 52 53 /** 54 * Capabilities that will be mapped to telecom connection 55 * capabilities. 56 */ 57 public static class Capability { 58 59 /** 60 * For an IMS video call, indicates that the local side of the call supports downgrading 61 * from a video call to an audio-only call. 62 */ 63 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL = 0x00000001; 64 65 /** 66 * For an IMS video call, indicates that the peer supports downgrading to an audio-only 67 * call. 68 */ 69 public static final int SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE = 0x00000002; 70 71 /** 72 * For an IMS call, indicates that the call supports video locally. 73 */ 74 public static final int SUPPORTS_VT_LOCAL_BIDIRECTIONAL = 0x00000004; 75 76 /** 77 * For an IMS call, indicates that the peer supports video. 78 */ 79 public static final int SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 0x00000008; 80 81 /** 82 * Indicates that the connection is an external connection (e.g. an instance of the class 83 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection}. 84 */ 85 public static final int IS_EXTERNAL_CONNECTION = 0x00000010; 86 87 /** 88 * Indicates that this external connection can be pulled from the remote device to the 89 * local device. 90 */ 91 public static final int IS_PULLABLE = 0x00000020; 92 } 93 94 /** 95 * Listener interface for events related to the connection which should be reported to the 96 * {@link android.telecom.Connection}. 97 */ 98 public interface Listener { onVideoStateChanged(int videoState)99 public void onVideoStateChanged(int videoState); onConnectionCapabilitiesChanged(int capability)100 public void onConnectionCapabilitiesChanged(int capability); onCallRadioTechChanged(@ilRadioTechnology int vrat)101 public void onCallRadioTechChanged(@RilRadioTechnology int vrat); onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)102 public void onVideoProviderChanged( 103 android.telecom.Connection.VideoProvider videoProvider); onAudioQualityChanged(int audioQuality)104 public void onAudioQualityChanged(int audioQuality); onConferenceParticipantsChanged(List<ConferenceParticipant> participants)105 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants); onCallSubstateChanged(int callSubstate)106 public void onCallSubstateChanged(int callSubstate); onMultipartyStateChanged(boolean isMultiParty)107 public void onMultipartyStateChanged(boolean isMultiParty); onConferenceMergedFailed()108 public void onConferenceMergedFailed(); onExtrasChanged(Bundle extras)109 public void onExtrasChanged(Bundle extras); onExitedEcmMode()110 public void onExitedEcmMode(); onCallPullFailed(Connection externalConnection)111 public void onCallPullFailed(Connection externalConnection); onHandoverToWifiFailed()112 public void onHandoverToWifiFailed(); onConnectionEvent(String event, Bundle extras)113 public void onConnectionEvent(String event, Bundle extras); onRttModifyRequestReceived()114 public void onRttModifyRequestReceived(); onRttModifyResponseReceived(int status)115 public void onRttModifyResponseReceived(int status); onDisconnect(int cause)116 public void onDisconnect(int cause); onRttInitiated()117 public void onRttInitiated(); onRttTerminated()118 public void onRttTerminated(); onOriginalConnectionReplaced(Connection newConnection)119 public void onOriginalConnectionReplaced(Connection newConnection); onIsNetworkEmergencyCallChanged(boolean isEmergencyCall)120 public void onIsNetworkEmergencyCallChanged(boolean isEmergencyCall); 121 } 122 123 /** 124 * Base listener implementation. 125 */ 126 public abstract static class ListenerBase implements Listener { 127 @Override onVideoStateChanged(int videoState)128 public void onVideoStateChanged(int videoState) {} 129 @Override onConnectionCapabilitiesChanged(int capability)130 public void onConnectionCapabilitiesChanged(int capability) {} 131 @Override onCallRadioTechChanged(@ilRadioTechnology int vrat)132 public void onCallRadioTechChanged(@RilRadioTechnology int vrat) {} 133 @Override onVideoProviderChanged( android.telecom.Connection.VideoProvider videoProvider)134 public void onVideoProviderChanged( 135 android.telecom.Connection.VideoProvider videoProvider) {} 136 @Override onAudioQualityChanged(int audioQuality)137 public void onAudioQualityChanged(int audioQuality) {} 138 @Override onConferenceParticipantsChanged(List<ConferenceParticipant> participants)139 public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {} 140 @Override onCallSubstateChanged(int callSubstate)141 public void onCallSubstateChanged(int callSubstate) {} 142 @Override onMultipartyStateChanged(boolean isMultiParty)143 public void onMultipartyStateChanged(boolean isMultiParty) {} 144 @Override onConferenceMergedFailed()145 public void onConferenceMergedFailed() {} 146 @Override onExtrasChanged(Bundle extras)147 public void onExtrasChanged(Bundle extras) {} 148 @Override onExitedEcmMode()149 public void onExitedEcmMode() {} 150 @Override onCallPullFailed(Connection externalConnection)151 public void onCallPullFailed(Connection externalConnection) {} 152 @Override onHandoverToWifiFailed()153 public void onHandoverToWifiFailed() {} 154 @Override onConnectionEvent(String event, Bundle extras)155 public void onConnectionEvent(String event, Bundle extras) {} 156 @Override onRttModifyRequestReceived()157 public void onRttModifyRequestReceived() {} 158 @Override onRttModifyResponseReceived(int status)159 public void onRttModifyResponseReceived(int status) {} 160 @Override onDisconnect(int cause)161 public void onDisconnect(int cause) {} 162 @Override onRttInitiated()163 public void onRttInitiated() {} 164 @Override onRttTerminated()165 public void onRttTerminated() {} 166 @Override onOriginalConnectionReplaced(Connection newConnection)167 public void onOriginalConnectionReplaced(Connection newConnection) {} 168 @Override onIsNetworkEmergencyCallChanged(boolean isEmergencyCall)169 public void onIsNetworkEmergencyCallChanged(boolean isEmergencyCall) {} 170 } 171 172 public static final int AUDIO_QUALITY_STANDARD = 1; 173 public static final int AUDIO_QUALITY_HIGH_DEFINITION = 2; 174 175 /** 176 * The telecom internal call ID associated with this connection. Only to be used for debugging 177 * purposes. 178 */ 179 private String mTelecomCallId; 180 181 //Caller Name Display 182 @UnsupportedAppUsage 183 protected String mCnapName; 184 @UnsupportedAppUsage 185 protected int mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED; 186 @UnsupportedAppUsage 187 protected String mAddress; // MAY BE NULL!!! 188 // The VERSTAT number verification status; defaults to not verified. 189 protected @android.telecom.Connection.VerificationStatus int mNumberVerificationStatus = 190 android.telecom.Connection.VERIFICATION_STATUS_NOT_VERIFIED; 191 192 @UnsupportedAppUsage 193 protected String mDialString; // outgoing calls only 194 protected String[] mParticipantsToDial;// outgoing calls only 195 protected boolean mIsAdhocConference; 196 @UnsupportedAppUsage 197 protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED; 198 @UnsupportedAppUsage 199 protected boolean mIsIncoming; 200 /* 201 * These time/timespan values are based on System.currentTimeMillis(), 202 * i.e., "wall clock" time. 203 */ 204 protected long mCreateTime; 205 protected long mConnectTime; 206 /* 207 * These time/timespan values are based on SystemClock.elapsedRealTime(), 208 * i.e., time since boot. They are appropriate for comparison and 209 * calculating deltas. 210 */ 211 protected long mConnectTimeReal; 212 @UnsupportedAppUsage 213 protected long mDuration; 214 protected long mHoldingStartTime; // The time when the Connection last transitioned 215 // into HOLDING 216 protected Connection mOrigConnection; 217 private List<PostDialListener> mPostDialListeners = new ArrayList<>(); 218 public Set<Listener> mListeners = new CopyOnWriteArraySet<>(); 219 220 protected boolean mNumberConverted = false; 221 protected String mConvertedNumber; 222 223 protected String mPostDialString; // outgoing calls only 224 protected int mNextPostDialChar; // index into postDialString 225 226 protected int mCause = DisconnectCause.NOT_DISCONNECTED; 227 protected PostDialState mPostDialState = PostDialState.NOT_STARTED; 228 229 // Store the current audio code 230 protected int mAudioCodec; 231 232 @UnsupportedAppUsage 233 private static String LOG_TAG = "Connection"; 234 235 Object mUserData; 236 private int mVideoState; 237 private int mConnectionCapabilities; 238 /** 239 * Determines the call radio technology for current connection. 240 * 241 * This is used to propagate the call radio technology to upper layer. 242 */ 243 private @RilRadioTechnology int mCallRadioTech = 244 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 245 private boolean mAudioModeIsVoip; 246 private int mAudioQuality; 247 private int mCallSubstate; 248 private android.telecom.Connection.VideoProvider mVideoProvider; 249 public Call.State mPreHandoverState = Call.State.IDLE; 250 private Bundle mExtras; 251 private int mPhoneType; 252 private boolean mAnsweringDisconnectsActiveCall; 253 private boolean mAllowAddCallDuringVideoCall; 254 private boolean mAllowHoldingVideoCall; 255 256 private boolean mIsEmergencyCall; 257 258 /** 259 * The emergency number information, only valid if {@link #isEmergencyCall} returns 260 * {@code true}. 261 */ 262 private EmergencyNumber mEmergencyNumberInfo; 263 264 /** 265 * Whether the call is from emergency dialer, only valid if {@link #isEmergencyCall} returns 266 * {@code true}. 267 */ 268 private boolean mHasKnownUserIntentEmergency; 269 270 /** 271 * When {@code true}, the network has indicated that this is an emergency call. 272 */ 273 private boolean mIsNetworkIdentifiedEmergencyCall; 274 275 /** 276 * Used to indicate that this originated from pulling a {@link android.telecom.Connection} with 277 * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL}. 278 */ 279 private boolean mIsPulledCall = false; 280 281 /** 282 * Where {@link #mIsPulledCall} is {@code true}, contains the dialog Id of the external call 283 * which is being pulled (e.g. 284 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection#getCallId()}). 285 */ 286 private int mPulledDialogId; 287 288 @UnsupportedAppUsage Connection(int phoneType)289 protected Connection(int phoneType) { 290 mPhoneType = phoneType; 291 } 292 293 /* Instance Methods */ 294 295 /** 296 * @return The telecom internal call ID associated with this connection. Only to be used for 297 * debugging purposes. 298 */ getTelecomCallId()299 public String getTelecomCallId() { 300 return mTelecomCallId; 301 } 302 303 /** 304 * Sets the telecom call ID associated with this connection. 305 * 306 * @param telecomCallId The telecom call ID. 307 */ setTelecomCallId(String telecomCallId)308 public void setTelecomCallId(String telecomCallId) { 309 mTelecomCallId = telecomCallId; 310 } 311 312 /** 313 * Gets address (e.g. phone number) associated with connection. 314 * TODO: distinguish reasons for unavailability 315 * 316 * @return address or null if unavailable 317 */ 318 319 @UnsupportedAppUsage getAddress()320 public String getAddress() { 321 return mAddress; 322 } 323 324 /** 325 * Gets the participants address (e.g. phone number) associated with connection. 326 * 327 * @return address or null if unavailable 328 */ getParticipantsToDial()329 public String[] getParticipantsToDial() { 330 return mParticipantsToDial; 331 } 332 333 // return whether connection is AdhocConference or not isAdhocConference()334 public boolean isAdhocConference() { 335 return mIsAdhocConference; 336 } 337 338 /** 339 * Gets CNAP name associated with connection. 340 * @return cnap name or null if unavailable 341 */ getCnapName()342 public String getCnapName() { 343 return mCnapName; 344 } 345 346 /** 347 * Get original dial string. 348 * @return original dial string or null if unavailable 349 */ getOrigDialString()350 public String getOrigDialString(){ 351 return null; 352 } 353 354 /** 355 * Get the number, as set by {@link #restoreDialedNumberAfterConversion(String)}. 356 * @return The converted number. 357 */ 358 @VisibleForTesting getConvertedNumber()359 public String getConvertedNumber() { 360 return mConvertedNumber; 361 } 362 363 /** 364 * Gets CNAP presentation associated with connection. 365 * @return cnap name or null if unavailable 366 */ 367 getCnapNamePresentation()368 public int getCnapNamePresentation() { 369 return mCnapNamePresentation; 370 } 371 372 /** 373 * @return Call that owns this Connection, or null if none 374 */ 375 @UnsupportedAppUsage getCall()376 public abstract Call getCall(); 377 378 /** 379 * Connection create time in currentTimeMillis() format 380 * Basically, set when object is created. 381 * Effectively, when an incoming call starts ringing or an 382 * outgoing call starts dialing 383 */ 384 @UnsupportedAppUsage getCreateTime()385 public long getCreateTime() { 386 return mCreateTime; 387 } 388 389 /** 390 * Connection connect time in currentTimeMillis() format. 391 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 392 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 393 * Returns 0 before then. 394 */ 395 @UnsupportedAppUsage getConnectTime()396 public long getConnectTime() { 397 return mConnectTime; 398 } 399 400 /** 401 * Sets the Connection connect time in currentTimeMillis() format. 402 * 403 * @param connectTime the new connect time. 404 */ setConnectTime(long connectTime)405 public void setConnectTime(long connectTime) { 406 mConnectTime = connectTime; 407 } 408 409 /** 410 * Sets the Connection connect time in {@link SystemClock#elapsedRealtime()} format. 411 * 412 * @param connectTimeReal the new connect time. 413 */ setConnectTimeReal(long connectTimeReal)414 public void setConnectTimeReal(long connectTimeReal) { 415 mConnectTimeReal = connectTimeReal; 416 } 417 418 /** 419 * Connection connect time in elapsedRealtime() format. 420 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 421 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 422 * Returns 0 before then. 423 */ getConnectTimeReal()424 public long getConnectTimeReal() { 425 return mConnectTimeReal; 426 } 427 428 /** 429 * Disconnect time in currentTimeMillis() format. 430 * The time when this Connection makes a transition into ENDED or FAIL. 431 * Returns 0 before then. 432 */ 433 @UnsupportedAppUsage getDisconnectTime()434 public abstract long getDisconnectTime(); 435 436 /** 437 * Returns the number of milliseconds the call has been connected, 438 * or 0 if the call has never connected. 439 * If the call is still connected, then returns the elapsed 440 * time since connect. 441 */ 442 @UnsupportedAppUsage getDurationMillis()443 public long getDurationMillis() { 444 if (mConnectTimeReal == 0) { 445 return 0; 446 } else if (mDuration == 0) { 447 return SystemClock.elapsedRealtime() - mConnectTimeReal; 448 } else { 449 return mDuration; 450 } 451 } 452 453 /** 454 * The time when this Connection last transitioned into HOLDING 455 * in elapsedRealtime() format. 456 * Returns 0, if it has never made a transition into HOLDING. 457 */ getHoldingStartTime()458 public long getHoldingStartTime() { 459 return mHoldingStartTime; 460 } 461 462 /** 463 * If this connection is HOLDING, return the number of milliseconds 464 * that it has been on hold for (approximately). 465 * If this connection is in any other state, return 0. 466 */ 467 getHoldDurationMillis()468 public abstract long getHoldDurationMillis(); 469 470 /** 471 * Returns call disconnect cause. Values are defined in 472 * {@link android.telephony.DisconnectCause}. If the call is not yet 473 * disconnected, NOT_DISCONNECTED is returned. 474 */ 475 @UnsupportedAppUsage getDisconnectCause()476 public int getDisconnectCause() { 477 return mCause; 478 } 479 480 /** 481 * Returns a string disconnect cause which is from vendor. 482 * Vendors may use this string to explain the underline causes of failed calls. 483 * There is no guarantee that it is non-null nor it'll have meaningful stable values. 484 * Only use it when getDisconnectCause() returns a value that is not specific enough, like 485 * ERROR_UNSPECIFIED. 486 */ getVendorDisconnectCause()487 public abstract String getVendorDisconnectCause(); 488 489 /** 490 * Returns true of this connection originated elsewhere 491 * ("MT" or mobile terminated; another party called this terminal) 492 * or false if this call originated here (MO or mobile originated). 493 */ 494 @UnsupportedAppUsage isIncoming()495 public boolean isIncoming() { 496 return mIsIncoming; 497 } 498 499 /** 500 * Sets whether this call is an incoming call or not. 501 * @param isIncoming {@code true} if the call is an incoming call, {@code false} if it is an 502 * outgoing call. 503 */ setIsIncoming(boolean isIncoming)504 public void setIsIncoming(boolean isIncoming) { 505 mIsIncoming = isIncoming; 506 } 507 508 /** 509 * Checks if the connection is for an emergency call. 510 * 511 * @return {@code true} if the call is an emergency call 512 * or {@code false} otherwise. 513 */ isEmergencyCall()514 public boolean isEmergencyCall() { 515 return mIsEmergencyCall; 516 } 517 518 /** 519 * Get the emergency number info. The value is valid only if {@link #isEmergencyCall()} 520 * returns {@code true}. 521 * 522 * @return the emergency number info 523 */ getEmergencyNumberInfo()524 public EmergencyNumber getEmergencyNumberInfo() { 525 return mEmergencyNumberInfo; 526 } 527 528 /** 529 * Checks if we have known the user's intent for the call is emergency. 530 * 531 * This is only used to specify when the dialed number is ambiguous, identified as both 532 * emergency number and any other non-emergency number; e.g. in some situation, 611 could 533 * be both an emergency number in a country and a non-emergency number of a carrier's 534 * customer service hotline. 535 * 536 * @return whether the call is from emergency dialer 537 */ hasKnownUserIntentEmergency()538 public boolean hasKnownUserIntentEmergency() { 539 return mHasKnownUserIntentEmergency; 540 } 541 542 /** 543 * Set the emergency number information if it is an emergency call. 544 * 545 * @hide 546 */ setEmergencyCallInfo(CallTracker ct)547 public void setEmergencyCallInfo(CallTracker ct) { 548 if (ct != null) { 549 Phone phone = ct.getPhone(); 550 if (phone != null) { 551 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker(); 552 if (tracker != null) { 553 EmergencyNumber num = tracker.getEmergencyNumber(mAddress); 554 if (num != null) { 555 mIsEmergencyCall = true; 556 mEmergencyNumberInfo = num; 557 } else { 558 Rlog.e(TAG, "setEmergencyCallInfo: emergency number is null"); 559 } 560 } else { 561 Rlog.e(TAG, "setEmergencyCallInfo: emergency number tracker is null"); 562 } 563 } else { 564 Rlog.e(TAG, "setEmergencyCallInfo: phone is null"); 565 } 566 } else { 567 Rlog.e(TAG, "setEmergencyCallInfo: call tracker is null"); 568 } 569 } 570 571 /** 572 * Set if we have known the user's intent for the call is emergency. 573 * 574 * This is only used to specify when the dialed number is ambiguous, identified as both 575 * emergency number and any other non-emergency number; e.g. in some situation, 611 could 576 * be both an emergency number in a country and a non-emergency number of a carrier's 577 * customer service hotline. 578 * 579 * @hide 580 */ setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency)581 public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) { 582 mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency; 583 } 584 585 /** 586 * If this Connection is connected, then it is associated with 587 * a Call. 588 * 589 * Returns getCall().getState() or Call.State.IDLE if not 590 * connected 591 */ 592 @UnsupportedAppUsage getState()593 public Call.State getState() { 594 Call c; 595 596 c = getCall(); 597 598 if (c == null) { 599 return Call.State.IDLE; 600 } else { 601 return c.getState(); 602 } 603 } 604 605 /** 606 * If this connection went through handover return the state of the 607 * call that contained this connection before handover. 608 */ getStateBeforeHandover()609 public Call.State getStateBeforeHandover() { 610 return mPreHandoverState; 611 } 612 613 /** 614 * Get the details of conference participants. Expected to be 615 * overwritten by the Connection subclasses. 616 */ getConferenceParticipants()617 public List<ConferenceParticipant> getConferenceParticipants() { 618 Call c; 619 620 c = getCall(); 621 622 if (c == null) { 623 return null; 624 } else { 625 return c.getConferenceParticipants(); 626 } 627 } 628 629 /** 630 * isAlive() 631 * 632 * @return true if the connection isn't disconnected 633 * (could be active, holding, ringing, dialing, etc) 634 */ 635 @UnsupportedAppUsage 636 public boolean isAlive()637 isAlive() { 638 return getState().isAlive(); 639 } 640 641 /** 642 * Returns true if Connection is connected and is INCOMING or WAITING 643 */ 644 public boolean isRinging()645 isRinging() { 646 return getState().isRinging(); 647 } 648 649 /** 650 * 651 * @return the userdata set in setUserData() 652 */ 653 @UnsupportedAppUsage getUserData()654 public Object getUserData() { 655 return mUserData; 656 } 657 658 /** 659 * 660 * @param userdata user can store an any userdata in the Connection object. 661 */ setUserData(Object userdata)662 public void setUserData(Object userdata) { 663 mUserData = userdata; 664 } 665 666 /** 667 * Deflect individual Connection 668 */ deflect(String number)669 public abstract void deflect(String number) throws CallStateException; 670 671 /** 672 * Transfer individual Connection 673 */ transfer(String number, boolean isConfirmationRequired)674 public abstract void transfer(String number, boolean isConfirmationRequired) 675 throws CallStateException; 676 677 /** 678 * Transfer individual Connection for consultative transfer 679 */ consultativeTransfer(Connection other)680 public abstract void consultativeTransfer(Connection other) throws CallStateException; 681 682 /** 683 * Hangup individual Connection 684 */ 685 @UnsupportedAppUsage hangup()686 public abstract void hangup() throws CallStateException; 687 688 /** 689 * Separate this call from its owner Call and assigns it to a new Call 690 * (eg if it is currently part of a Conference call 691 * TODO: Throw exception? Does GSM require error display on failure here? 692 */ separate()693 public abstract void separate() throws CallStateException; 694 695 public enum PostDialState { 696 @UnsupportedAppUsage 697 NOT_STARTED, /* The post dial string playback hasn't 698 been started, or this call is not yet 699 connected, or this is an incoming call */ 700 @UnsupportedAppUsage 701 STARTED, /* The post dial string playback has begun */ 702 @UnsupportedAppUsage 703 WAIT, /* The post dial string playback is waiting for a 704 call to proceedAfterWaitChar() */ 705 @UnsupportedAppUsage 706 WILD, /* The post dial string playback is waiting for a 707 call to proceedAfterWildChar() */ 708 @UnsupportedAppUsage 709 COMPLETE, /* The post dial string playback is complete */ 710 @UnsupportedAppUsage 711 CANCELLED, /* The post dial string playback was cancelled 712 with cancelPostDial() */ 713 PAUSE /* The post dial string playback is pausing for a 714 call to processNextPostDialChar*/ 715 } 716 clearUserData()717 public void clearUserData(){ 718 mUserData = null; 719 } 720 addPostDialListener(PostDialListener listener)721 public void addPostDialListener(PostDialListener listener) { 722 if (!mPostDialListeners.contains(listener)) { 723 mPostDialListeners.add(listener); 724 } 725 } 726 removePostDialListener(PostDialListener listener)727 public final void removePostDialListener(PostDialListener listener) { 728 mPostDialListeners.remove(listener); 729 } 730 clearPostDialListeners()731 protected final void clearPostDialListeners() { 732 if (mPostDialListeners != null) { 733 mPostDialListeners.clear(); 734 } 735 } 736 notifyPostDialListeners()737 protected final void notifyPostDialListeners() { 738 if (getPostDialState() == PostDialState.WAIT) { 739 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 740 listener.onPostDialWait(); 741 } 742 } 743 } 744 notifyPostDialListenersNextChar(char c)745 protected final void notifyPostDialListenersNextChar(char c) { 746 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 747 listener.onPostDialChar(c); 748 } 749 } 750 getPostDialState()751 public PostDialState getPostDialState() { 752 return mPostDialState; 753 } 754 755 /** 756 * Returns the portion of the post dial string that has not 757 * yet been dialed, or "" if none 758 */ getRemainingPostDialString()759 public String getRemainingPostDialString() { 760 if (mPostDialState == PostDialState.CANCELLED 761 || mPostDialState == PostDialState.COMPLETE 762 || mPostDialString == null 763 || mPostDialString.length() <= mNextPostDialChar) { 764 return ""; 765 } 766 767 return mPostDialString.substring(mNextPostDialChar); 768 } 769 770 /** 771 * See Phone.setOnPostDialWaitCharacter() 772 */ 773 proceedAfterWaitChar()774 public abstract void proceedAfterWaitChar(); 775 776 /** 777 * See Phone.setOnPostDialWildCharacter() 778 */ proceedAfterWildChar(String str)779 public abstract void proceedAfterWildChar(String str); 780 /** 781 * Cancel any post 782 */ cancelPostDial()783 public abstract void cancelPostDial(); 784 785 /** Called when the connection has been disconnected */ onDisconnect(int cause)786 public boolean onDisconnect(int cause) { 787 return false; 788 } 789 790 /** 791 * Returns the caller id presentation type for incoming and waiting calls 792 * @return one of PRESENTATION_* 793 */ getNumberPresentation()794 public abstract int getNumberPresentation(); 795 796 /** 797 * Returns the User to User Signaling (UUS) information associated with 798 * incoming and waiting calls 799 * @return UUSInfo containing the UUS userdata. 800 */ getUUSInfo()801 public abstract UUSInfo getUUSInfo(); 802 803 /** 804 * Returns the CallFail reason provided by the RIL with the result of 805 * RIL_REQUEST_LAST_CALL_FAIL_CAUSE 806 */ getPreciseDisconnectCause()807 public abstract int getPreciseDisconnectCause(); 808 809 /** 810 * Returns the original Connection instance associated with 811 * this Connection 812 */ getOrigConnection()813 public Connection getOrigConnection() { 814 return mOrigConnection; 815 } 816 817 /** 818 * Returns whether the original ImsPhoneConnection was a member 819 * of a conference call 820 * @return valid only when getOrigConnection() is not null 821 */ isMultiparty()822 public abstract boolean isMultiparty(); 823 824 /** 825 * Applicable only for IMS Call. Determines if this call is the origin of the conference call 826 * (i.e. {@code #isConferenceHost()} is {@code true}), or if it is a member of a conference 827 * hosted on another device. 828 * 829 * @return {@code true} if this call is the origin of the conference call it is a member of, 830 * {@code false} otherwise. 831 */ isConferenceHost()832 public boolean isConferenceHost() { 833 return false; 834 } 835 836 /** 837 * Applicable only for IMS Call. Determines if a connection is a member of a conference hosted 838 * on another device. 839 * 840 * @return {@code true} if the connection is a member of a conference hosted on another device. 841 */ isMemberOfPeerConference()842 public boolean isMemberOfPeerConference() { 843 return false; 844 } 845 migrateFrom(Connection c)846 public void migrateFrom(Connection c) { 847 if (c == null) return; 848 mListeners = c.mListeners; 849 mDialString = c.getOrigDialString(); 850 mCreateTime = c.getCreateTime(); 851 mConnectTime = c.getConnectTime(); 852 mConnectTimeReal = c.getConnectTimeReal(); 853 mHoldingStartTime = c.getHoldingStartTime(); 854 mOrigConnection = c.getOrigConnection(); 855 mPostDialString = c.mPostDialString; 856 mNextPostDialChar = c.mNextPostDialChar; 857 mPostDialState = c.mPostDialState; 858 859 // Migrate Emergency call parameters 860 mIsEmergencyCall = c.isEmergencyCall(); 861 mEmergencyNumberInfo = c.getEmergencyNumberInfo(); 862 mHasKnownUserIntentEmergency = c.hasKnownUserIntentEmergency(); 863 } 864 865 /** 866 * Assign a listener to be notified of state changes. 867 * 868 * @param listener A listener. 869 */ addListener(Listener listener)870 public void addListener(Listener listener) { 871 mListeners.add(listener); 872 } 873 874 /** 875 * Removes a listener. 876 * 877 * @param listener A listener. 878 */ removeListener(Listener listener)879 public final void removeListener(Listener listener) { 880 mListeners.remove(listener); 881 } 882 883 /** 884 * Returns the current video state of the connection. 885 * 886 * @return The video state of the connection. 887 */ getVideoState()888 public int getVideoState() { 889 return mVideoState; 890 } 891 892 /** 893 * Called to get Connection capabilities.Returns Capabilities bitmask. 894 * @See Connection.Capability. 895 */ getConnectionCapabilities()896 public int getConnectionCapabilities() { 897 return mConnectionCapabilities; 898 } 899 900 /** 901 * @return {@code} true if the connection has the specified capabilities. 902 */ hasCapabilities(int connectionCapabilities)903 public boolean hasCapabilities(int connectionCapabilities) { 904 return (mConnectionCapabilities & connectionCapabilities) == connectionCapabilities; 905 } 906 907 /** 908 * Applies a capability to a capabilities bit-mask. 909 * 910 * @param capabilities The capabilities bit-mask. 911 * @param capability The capability to apply. 912 * @return The capabilities bit-mask with the capability applied. 913 */ addCapability(int capabilities, int capability)914 public static int addCapability(int capabilities, int capability) { 915 return capabilities | capability; 916 } 917 918 /** 919 * Removes a capability to a capabilities bit-mask. 920 * 921 * @param capabilities The capabilities bit-mask. 922 * @param capability The capability to remove. 923 * @return The capabilities bit-mask with the capability removed. 924 */ removeCapability(int capabilities, int capability)925 public static int removeCapability(int capabilities, int capability) { 926 return capabilities & ~capability; 927 } 928 929 /** 930 * Returns whether the connection is using a wifi network. 931 * 932 * @return {@code True} if the connection is using a wifi network. 933 */ isWifi()934 public boolean isWifi() { 935 return getCallRadioTech() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; 936 } 937 938 /** 939 * Returns radio technology is used for the connection. 940 * 941 * @return the RIL Voice Radio Technology used for current connection, 942 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 943 */ getCallRadioTech()944 public @RilRadioTechnology int getCallRadioTech() { 945 return mCallRadioTech; 946 } 947 948 /** 949 * Returns whether the connection uses voip audio mode 950 * 951 * @return {@code True} if the connection uses voip audio mode 952 */ getAudioModeIsVoip()953 public boolean getAudioModeIsVoip() { 954 return mAudioModeIsVoip; 955 } 956 957 /** 958 * Returns the {@link android.telecom.Connection.VideoProvider} for the connection. 959 * 960 * @return The {@link android.telecom.Connection.VideoProvider}. 961 */ getVideoProvider()962 public android.telecom.Connection.VideoProvider getVideoProvider() { 963 return mVideoProvider; 964 } 965 966 /** 967 * Returns the audio-quality for the connection. 968 * 969 * @return The audio quality for the connection. 970 */ getAudioQuality()971 public int getAudioQuality() { 972 return mAudioQuality; 973 } 974 975 976 /** 977 * Returns the current call substate of the connection. 978 * 979 * @return The call substate of the connection. 980 */ getCallSubstate()981 public int getCallSubstate() { 982 return mCallSubstate; 983 } 984 985 986 /** 987 * Sets the videoState for the current connection and reports the changes to all listeners. 988 * Valid video states are defined in {@link android.telecom.VideoProfile}. 989 * 990 * @return The video state. 991 */ 992 @UnsupportedAppUsage setVideoState(int videoState)993 public void setVideoState(int videoState) { 994 mVideoState = videoState; 995 for (Listener l : mListeners) { 996 l.onVideoStateChanged(mVideoState); 997 } 998 } 999 1000 /** 1001 * Called to set Connection capabilities. This will take Capabilities bitmask as input which is 1002 * converted from Capabilities constants. 1003 * 1004 * @See Connection.Capability. 1005 * @param capabilities The Capabilities bitmask. 1006 */ setConnectionCapabilities(int capabilities)1007 public void setConnectionCapabilities(int capabilities) { 1008 if (mConnectionCapabilities != capabilities) { 1009 mConnectionCapabilities = capabilities; 1010 for (Listener l : mListeners) { 1011 l.onConnectionCapabilitiesChanged(mConnectionCapabilities); 1012 } 1013 } 1014 } 1015 1016 /** 1017 * Sets RIL voice radio technology used for current connection. 1018 * 1019 * @param vrat the RIL voice radio technology for current connection, 1020 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 1021 */ setCallRadioTech(@ilRadioTechnology int vrat)1022 public void setCallRadioTech(@RilRadioTechnology int vrat) { 1023 if (mCallRadioTech == vrat) { 1024 return; 1025 } 1026 mCallRadioTech = vrat; 1027 for (Listener l : mListeners) { 1028 l.onCallRadioTechChanged(vrat); 1029 } 1030 } 1031 1032 /** 1033 * Set the voip audio mode for the connection 1034 * 1035 * @param isVoip {@code True} if voip audio mode is being used. 1036 */ setAudioModeIsVoip(boolean isVoip)1037 public void setAudioModeIsVoip(boolean isVoip) { 1038 mAudioModeIsVoip = isVoip; 1039 } 1040 1041 /** 1042 * Set the audio quality for the connection. 1043 * 1044 * @param audioQuality The audio quality. 1045 */ setAudioQuality(int audioQuality)1046 public void setAudioQuality(int audioQuality) { 1047 mAudioQuality = audioQuality; 1048 for (Listener l : mListeners) { 1049 l.onAudioQualityChanged(mAudioQuality); 1050 } 1051 } 1052 1053 /** 1054 * Notifies listeners that connection extras has changed. 1055 * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent 1056 * modifications to the extras Bundle do not affect Bundle operations in the onExtrasChanged 1057 * listeners. 1058 */ setConnectionExtras(Bundle extras)1059 public void setConnectionExtras(Bundle extras) { 1060 if (extras != null) { 1061 mExtras = new Bundle(extras); 1062 1063 int previousCount = mExtras.size(); 1064 // Prevent vendors from passing in extras other than primitive types and android API 1065 // parcelables. 1066 mExtras = TelephonyUtils.filterValues(mExtras); 1067 int filteredCount = mExtras.size(); 1068 if (filteredCount != previousCount) { 1069 Rlog.i(TAG, "setConnectionExtras: filtering " + (previousCount - filteredCount) 1070 + " invalid extras."); 1071 } 1072 } else { 1073 mExtras = null; 1074 } 1075 1076 for (Listener l : mListeners) { 1077 l.onExtrasChanged(mExtras); 1078 } 1079 } 1080 1081 /** 1082 * Retrieves the current connection extras. 1083 * @return the connection extras. 1084 */ getConnectionExtras()1085 public Bundle getConnectionExtras() { 1086 return mExtras == null ? null : new Bundle(mExtras); 1087 } 1088 1089 /** 1090 * @return {@code true} if answering the call will cause the current active call to be 1091 * disconnected, {@code false} otherwise. 1092 */ isActiveCallDisconnectedOnAnswer()1093 public boolean isActiveCallDisconnectedOnAnswer() { 1094 return mAnsweringDisconnectsActiveCall; 1095 } 1096 1097 /** 1098 * Sets whether answering this call will cause the active call to be disconnected. 1099 * <p> 1100 * Should only be set {@code true} if there is an active call and this call is ringing. 1101 * 1102 * @param answeringDisconnectsActiveCall {@code true} if answering the call will call the active 1103 * call to be disconnected. 1104 */ setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall)1105 public void setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall) { 1106 mAnsweringDisconnectsActiveCall = answeringDisconnectsActiveCall; 1107 } 1108 shouldAllowAddCallDuringVideoCall()1109 public boolean shouldAllowAddCallDuringVideoCall() { 1110 return mAllowAddCallDuringVideoCall; 1111 } 1112 setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall)1113 public void setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall) { 1114 mAllowAddCallDuringVideoCall = allowAddCallDuringVideoCall; 1115 } 1116 shouldAllowHoldingVideoCall()1117 public boolean shouldAllowHoldingVideoCall() { 1118 return mAllowHoldingVideoCall; 1119 } 1120 setAllowHoldingVideoCall(boolean allowHoldingVideoCall)1121 public void setAllowHoldingVideoCall(boolean allowHoldingVideoCall) { 1122 mAllowHoldingVideoCall = allowHoldingVideoCall; 1123 } 1124 1125 /** 1126 * Sets whether the connection is the result of an external call which was pulled to the local 1127 * device. 1128 * 1129 * @param isPulledCall {@code true} if this connection is the result of pulling an external call 1130 * to the local device. 1131 */ setIsPulledCall(boolean isPulledCall)1132 public void setIsPulledCall(boolean isPulledCall) { 1133 mIsPulledCall = isPulledCall; 1134 } 1135 isPulledCall()1136 public boolean isPulledCall() { 1137 return mIsPulledCall; 1138 } 1139 1140 /** 1141 * For an external call which is being pulled (e.g. {@link #isPulledCall()} is {@code true}), 1142 * sets the dialog Id for the external call. Used to handle failures to pull a call so that the 1143 * pulled call can be reconciled with its original external connection. 1144 * 1145 * @param pulledDialogId The dialog id associated with a pulled call. 1146 */ setPulledDialogId(int pulledDialogId)1147 public void setPulledDialogId(int pulledDialogId) { 1148 mPulledDialogId = pulledDialogId; 1149 } 1150 getPulledDialogId()1151 public int getPulledDialogId() { 1152 return mPulledDialogId; 1153 } 1154 1155 /** 1156 * Sets the call substate for the current connection and reports the changes to all listeners. 1157 * Valid call substates are defined in {@link android.telecom.Connection}. 1158 * 1159 * @return The call substate. 1160 */ setCallSubstate(int callSubstate)1161 public void setCallSubstate(int callSubstate) { 1162 mCallSubstate = callSubstate; 1163 for (Listener l : mListeners) { 1164 l.onCallSubstateChanged(mCallSubstate); 1165 } 1166 } 1167 1168 /** 1169 * Sets the {@link android.telecom.Connection.VideoProvider} for the connection. 1170 * 1171 * @param videoProvider The video call provider. 1172 */ setVideoProvider(android.telecom.Connection.VideoProvider videoProvider)1173 public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 1174 mVideoProvider = videoProvider; 1175 for (Listener l : mListeners) { 1176 l.onVideoProviderChanged(mVideoProvider); 1177 } 1178 } 1179 1180 /** 1181 * {@link CallTracker#convertNumberIfNecessary(Phone, String)} can be used to convert a dialed 1182 * number to another number based on carrier config. This is used where a carrier wishes to 1183 * redirect certain short codes such as *55 to another number (e.g. a 1-800 service number). 1184 * The {@link CallTracker} sub-classes call 1185 * {@link CallTracker#convertNumberIfNecessary(Phone, String)} to retrieve the newly converted 1186 * number and instantiate the {@link Connection} instance using the converted number so that the 1187 * system will dial out the substitution number instead of the originally dialed one. This gem 1188 * of a method is called after the dialing process to restore the originally dialed number and 1189 * keep track of the fact that a converted number was used to place the call. 1190 * @param oriNumber The original number prior to conversion. 1191 */ restoreDialedNumberAfterConversion(String oriNumber)1192 public void restoreDialedNumberAfterConversion(String oriNumber) { 1193 mNumberConverted = true; 1194 mConvertedNumber = mAddress; 1195 mAddress = oriNumber; 1196 mDialString = oriNumber; 1197 } 1198 1199 /** 1200 * Changes the address and presentation for this call. 1201 * @param newAddress The new address. 1202 * @param numberPresentation The number presentation for the address. 1203 */ setAddress(String newAddress, int numberPresentation)1204 public void setAddress(String newAddress, int numberPresentation) { 1205 Rlog.i(TAG, "setAddress = " + newAddress); 1206 mAddress = newAddress; 1207 mNumberPresentation = numberPresentation; 1208 } 1209 setDialString(String newDialString)1210 public void setDialString(String newDialString) { 1211 mDialString = newDialString; 1212 } 1213 1214 /** 1215 * Notifies listeners of a change to conference participant(s). 1216 * 1217 * @param conferenceParticipants The participant(s). 1218 */ updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants)1219 public void updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants) { 1220 for (Listener l : mListeners) { 1221 l.onConferenceParticipantsChanged(conferenceParticipants); 1222 } 1223 } 1224 1225 /** 1226 * Notifies listeners of a change to the multiparty state of the connection. 1227 * 1228 * @param isMultiparty The participant(s). 1229 */ updateMultipartyState(boolean isMultiparty)1230 public void updateMultipartyState(boolean isMultiparty) { 1231 for (Listener l : mListeners) { 1232 l.onMultipartyStateChanged(isMultiparty); 1233 } 1234 } 1235 1236 /** 1237 * Notifies listeners of a failure in merging this connection with the background connection. 1238 */ onConferenceMergeFailed()1239 public void onConferenceMergeFailed() { 1240 for (Listener l : mListeners) { 1241 l.onConferenceMergedFailed(); 1242 } 1243 } 1244 1245 /** 1246 * Notifies that the underlying phone has exited ECM mode. 1247 */ onExitedEcmMode()1248 public void onExitedEcmMode() { 1249 for (Listener l : mListeners) { 1250 l.onExitedEcmMode(); 1251 } 1252 } 1253 1254 /** 1255 * Notifies the connection that a call to {@link #pullExternalCall()} has failed to pull the 1256 * call to the local device. 1257 * 1258 * @param externalConnection The original 1259 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection} from which the 1260 * pull was initiated. 1261 */ onCallPullFailed(Connection externalConnection)1262 public void onCallPullFailed(Connection externalConnection) { 1263 for (Listener l : mListeners) { 1264 l.onCallPullFailed(externalConnection); 1265 } 1266 } 1267 onOriginalConnectionReplaced(Connection newConnection)1268 public void onOriginalConnectionReplaced(Connection newConnection) { 1269 for (Listener l : mListeners) { 1270 l.onOriginalConnectionReplaced(newConnection); 1271 } 1272 } 1273 /** 1274 * Notifies the connection that there was a failure while handing over to WIFI. 1275 */ onHandoverToWifiFailed()1276 public void onHandoverToWifiFailed() { 1277 for (Listener l : mListeners) { 1278 l.onHandoverToWifiFailed(); 1279 } 1280 } 1281 1282 /** 1283 * Notifies the connection of a connection event. 1284 */ onConnectionEvent(String event, Bundle extras)1285 public void onConnectionEvent(String event, Bundle extras) { 1286 for (Listener l : mListeners) { 1287 l.onConnectionEvent(event, extras); 1288 } 1289 } 1290 1291 /** 1292 * Notifies this Connection of a request to disconnect a participant of the conference managed 1293 * by the connection. 1294 * 1295 * @param endpoint the {@link Uri} of the participant to disconnect. 1296 */ onDisconnectConferenceParticipant(Uri endpoint)1297 public void onDisconnectConferenceParticipant(Uri endpoint) { 1298 } 1299 1300 /** 1301 * Called by a {@link android.telecom.Connection} to indicate that this call should be pulled 1302 * to the local device. 1303 */ pullExternalCall()1304 public void pullExternalCall() { 1305 } 1306 onRttModifyRequestReceived()1307 public void onRttModifyRequestReceived() { 1308 for (Listener l : mListeners) { 1309 l.onRttModifyRequestReceived(); 1310 } 1311 } 1312 onRttModifyResponseReceived(int status)1313 public void onRttModifyResponseReceived(int status) { 1314 for (Listener l : mListeners) { 1315 l.onRttModifyResponseReceived(status); 1316 } 1317 } 1318 onRttInitiated()1319 public void onRttInitiated() { 1320 for (Listener l : mListeners) { 1321 l.onRttInitiated(); 1322 } 1323 } 1324 onRttTerminated()1325 public void onRttTerminated() { 1326 for (Listener l : mListeners) { 1327 l.onRttTerminated(); 1328 } 1329 } 1330 /** 1331 * Notify interested parties that this connection disconnected. 1332 * {@code TelephonyConnection}, for example, uses this. 1333 * @param reason the disconnect code, per {@link DisconnectCause}. 1334 */ notifyDisconnect(int reason)1335 protected void notifyDisconnect(int reason) { 1336 Rlog.i(TAG, "notifyDisconnect: callId=" + getTelecomCallId() + ", reason=" + reason); 1337 for (Listener l : mListeners) { 1338 l.onDisconnect(reason); 1339 } 1340 } 1341 1342 /** 1343 * 1344 */ getPhoneType()1345 public int getPhoneType() { 1346 return mPhoneType; 1347 } 1348 1349 /** 1350 * Reset the Connection time and Duration 1351 */ resetConnectionTime()1352 public void resetConnectionTime() { 1353 if (mPhoneType == PhoneConstants.PHONE_TYPE_CDMA_LTE || 1354 mPhoneType == PhoneConstants.PHONE_TYPE_CDMA) { 1355 mConnectTime = System.currentTimeMillis(); 1356 mConnectTimeReal = SystemClock.elapsedRealtime(); 1357 mDuration = 0; 1358 } 1359 } 1360 1361 /** 1362 * Sets whether this {@link Connection} has been identified by the network as an emergency call. 1363 * @param isNetworkIdentifiedEmergencyCall {@code true} if ecall, {@code false} otherwise. 1364 */ setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall)1365 public void setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall) { 1366 mIsNetworkIdentifiedEmergencyCall = isNetworkIdentifiedEmergencyCall; 1367 for (Listener l : mListeners) { 1368 l.onIsNetworkEmergencyCallChanged(isNetworkIdentifiedEmergencyCall); 1369 } 1370 } 1371 1372 /** 1373 * @return Whether this {@link Connection} has been identified by the network as an emergency 1374 * call. 1375 */ isNetworkIdentifiedEmergencyCall()1376 public boolean isNetworkIdentifiedEmergencyCall() { 1377 return mIsNetworkIdentifiedEmergencyCall; 1378 } 1379 1380 /** 1381 * Build a human representation of a connection instance, suitable for debugging. 1382 * Don't log personal stuff unless in debug mode. 1383 * @return a string representing the internal state of this connection. 1384 */ toString()1385 public String toString() { 1386 StringBuilder str = new StringBuilder(128); 1387 1388 str.append(" callId: " + getTelecomCallId()); 1389 str.append(" objId: " + System.identityHashCode(this)); 1390 str.append(" isExternal: " + (((mConnectionCapabilities & Capability.IS_EXTERNAL_CONNECTION) 1391 == Capability.IS_EXTERNAL_CONNECTION) ? "Y" : "N")); 1392 if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) { 1393 str.append("addr: " + getAddress()) 1394 .append(" pres.: " + getNumberPresentation()) 1395 .append(" dial: " + getOrigDialString()) 1396 .append(" postdial: " + getRemainingPostDialString()) 1397 .append(" cnap name: " + getCnapName()) 1398 .append("(" + getCnapNamePresentation() + ")"); 1399 } 1400 str.append(" incoming: " + isIncoming()) 1401 .append(" state: " + getState()) 1402 .append(" post dial state: " + getPostDialState()); 1403 return str.toString(); 1404 } 1405 1406 /** 1407 * Get current audio codec. 1408 * @return current audio codec. 1409 */ getAudioCodec()1410 public int getAudioCodec() { 1411 return mAudioCodec; 1412 } 1413 1414 /** 1415 * @return The number verification status; only applicable for IMS calls. 1416 */ getNumberVerificationStatus()1417 public @android.telecom.Connection.VerificationStatus int getNumberVerificationStatus() { 1418 return mNumberVerificationStatus; 1419 } 1420 1421 /** 1422 * Sets the number verification status. 1423 * @param verificationStatus The new verification status 1424 */ setNumberVerificationStatus( @ndroid.telecom.Connection.VerificationStatus int verificationStatus)1425 public void setNumberVerificationStatus( 1426 @android.telecom.Connection.VerificationStatus int verificationStatus) { 1427 mNumberVerificationStatus = verificationStatus; 1428 } 1429 } 1430