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