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