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 Rlog.d(TAG, "setEmergencyCallInfo: enforce emergency routing eccCategory=" 698 + eccCategory); 699 List<String> emergencyUrns = dialArgs.intentExtras.getStringArrayList( 700 PhoneConstants.EXTRA_EMERGENCY_URNS); 701 if (emergencyUrns == null || emergencyUrns.isEmpty()) { 702 emergencyUrns = mEmergencyNumberInfo.getEmergencyUrns(); 703 } 704 mEmergencyNumberInfo = new EmergencyNumber(mEmergencyNumberInfo.getNumber(), 705 mEmergencyNumberInfo.getCountryIso(), 706 mEmergencyNumberInfo.getMnc(), 707 eccCategory, 708 emergencyUrns, 709 mEmergencyNumberInfo.getEmergencyNumberSourceBitmask(), 710 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY); 711 } 712 } 713 } 714 715 /** 716 * Set the non-detectable emergency number information. 717 */ setNonDetectableEmergencyCallInfo(int eccCategory, @NonNull List<String> emergencyUrns)718 public void setNonDetectableEmergencyCallInfo(int eccCategory, 719 @NonNull List<String> emergencyUrns) { 720 Rlog.d(TAG, "setNonDetectableEmergencyCallInfo: eccCategory=" + eccCategory 721 + ", emergencyUrns=" + emergencyUrns); 722 mIsEmergencyCall = true; 723 mEmergencyNumberInfo = new EmergencyNumber(mAddress, ""/*countryIso*/, ""/*mnc*/, 724 eccCategory, emergencyUrns, 725 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING, 726 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN); 727 } 728 729 /** 730 * Set if we have known the user's intent for the call is emergency. 731 * 732 * This is only used to specify when the dialed number is ambiguous, identified as both 733 * emergency number and any other non-emergency number; e.g. in some situation, 611 could 734 * be both an emergency number in a country and a non-emergency number of a carrier's 735 * customer service hotline. 736 * 737 * @hide 738 */ setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency)739 public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) { 740 mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency; 741 } 742 743 /** 744 * If this Connection is connected, then it is associated with 745 * a Call. 746 * 747 * Returns getCall().getState() or Call.State.IDLE if not 748 * connected 749 */ 750 @UnsupportedAppUsage getState()751 public Call.State getState() { 752 Call c; 753 754 c = getCall(); 755 756 if (c == null) { 757 return Call.State.IDLE; 758 } else { 759 return c.getState(); 760 } 761 } 762 763 /** 764 * If this connection went through handover return the state of the 765 * call that contained this connection before handover. 766 */ getStateBeforeHandover()767 public Call.State getStateBeforeHandover() { 768 return mPreHandoverState; 769 } 770 771 /** 772 * Get the details of conference participants. Expected to be 773 * overwritten by the Connection subclasses. 774 */ getConferenceParticipants()775 public List<ConferenceParticipant> getConferenceParticipants() { 776 Call c; 777 778 c = getCall(); 779 780 if (c == null) { 781 return null; 782 } else { 783 return c.getConferenceParticipants(); 784 } 785 } 786 787 /** 788 * isAlive() 789 * 790 * @return true if the connection isn't disconnected 791 * (could be active, holding, ringing, dialing, etc) 792 */ 793 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 794 public boolean isAlive()795 isAlive() { 796 return getState().isAlive(); 797 } 798 799 /** 800 * Returns true if Connection is connected and is INCOMING or WAITING 801 */ 802 public boolean isRinging()803 isRinging() { 804 return getState().isRinging(); 805 } 806 807 /** 808 * 809 * @return the userdata set in setUserData() 810 */ 811 @UnsupportedAppUsage getUserData()812 public Object getUserData() { 813 return mUserData; 814 } 815 816 /** 817 * 818 * @param userdata user can store an any userdata in the Connection object. 819 */ setUserData(Object userdata)820 public void setUserData(Object userdata) { 821 mUserData = userdata; 822 } 823 824 /** 825 * Deflect individual Connection 826 */ deflect(String number)827 public abstract void deflect(String number) throws CallStateException; 828 829 /** 830 * Transfer individual Connection 831 */ transfer(String number, boolean isConfirmationRequired)832 public abstract void transfer(String number, boolean isConfirmationRequired) 833 throws CallStateException; 834 835 /** 836 * Transfer individual Connection for consultative transfer 837 */ consultativeTransfer(Connection other)838 public abstract void consultativeTransfer(Connection other) throws CallStateException; 839 840 /** 841 * Hangup individual Connection 842 */ 843 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) hangup()844 public abstract void hangup() throws CallStateException; 845 846 /** 847 * Separate this call from its owner Call and assigns it to a new Call 848 * (eg if it is currently part of a Conference call 849 * TODO: Throw exception? Does GSM require error display on failure here? 850 */ separate()851 public abstract void separate() throws CallStateException; 852 853 public enum PostDialState { 854 @UnsupportedAppUsage 855 NOT_STARTED, /* The post dial string playback hasn't 856 been started, or this call is not yet 857 connected, or this is an incoming call */ 858 @UnsupportedAppUsage 859 STARTED, /* The post dial string playback has begun */ 860 @UnsupportedAppUsage 861 WAIT, /* The post dial string playback is waiting for a 862 call to proceedAfterWaitChar() */ 863 @UnsupportedAppUsage 864 WILD, /* The post dial string playback is waiting for a 865 call to proceedAfterWildChar() */ 866 @UnsupportedAppUsage 867 COMPLETE, /* The post dial string playback is complete */ 868 @UnsupportedAppUsage 869 CANCELLED, /* The post dial string playback was cancelled 870 with cancelPostDial() */ 871 PAUSE /* The post dial string playback is pausing for a 872 call to processNextPostDialChar*/ 873 } 874 clearUserData()875 public void clearUserData(){ 876 mUserData = null; 877 } 878 addPostDialListener(PostDialListener listener)879 public void addPostDialListener(PostDialListener listener) { 880 if (!mPostDialListeners.contains(listener)) { 881 mPostDialListeners.add(listener); 882 } 883 } 884 removePostDialListener(PostDialListener listener)885 public final void removePostDialListener(PostDialListener listener) { 886 mPostDialListeners.remove(listener); 887 } 888 clearPostDialListeners()889 protected final void clearPostDialListeners() { 890 if (mPostDialListeners != null) { 891 mPostDialListeners.clear(); 892 } 893 } 894 notifyPostDialListeners()895 protected final void notifyPostDialListeners() { 896 if (getPostDialState() == PostDialState.WAIT) { 897 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 898 listener.onPostDialWait(); 899 } 900 } 901 } 902 notifyPostDialListenersNextChar(char c)903 protected final void notifyPostDialListenersNextChar(char c) { 904 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 905 listener.onPostDialChar(c); 906 } 907 } 908 getPostDialState()909 public PostDialState getPostDialState() { 910 return mPostDialState; 911 } 912 913 /** 914 * Returns the portion of the post dial string that has not 915 * yet been dialed, or "" if none 916 */ getRemainingPostDialString()917 public String getRemainingPostDialString() { 918 if (mPostDialState == PostDialState.CANCELLED 919 || mPostDialState == PostDialState.COMPLETE 920 || mPostDialString == null 921 || mPostDialString.length() <= mNextPostDialChar) { 922 return ""; 923 } 924 925 return mPostDialString.substring(mNextPostDialChar); 926 } 927 928 /** 929 * See Phone.setOnPostDialWaitCharacter() 930 */ 931 proceedAfterWaitChar()932 public abstract void proceedAfterWaitChar(); 933 934 /** 935 * See Phone.setOnPostDialWildCharacter() 936 */ proceedAfterWildChar(String str)937 public abstract void proceedAfterWildChar(String str); 938 /** 939 * Cancel any post 940 */ cancelPostDial()941 public abstract void cancelPostDial(); 942 943 /** Called when the connection has been disconnected */ onDisconnect(int cause)944 public boolean onDisconnect(int cause) { 945 return false; 946 } 947 948 /** 949 * Returns the caller id presentation type for incoming and waiting calls 950 * @return one of PRESENTATION_* 951 */ getNumberPresentation()952 public abstract int getNumberPresentation(); 953 954 /** 955 * Returns the User to User Signaling (UUS) information associated with 956 * incoming and waiting calls 957 * @return UUSInfo containing the UUS userdata. 958 */ getUUSInfo()959 public abstract UUSInfo getUUSInfo(); 960 961 /** 962 * Returns the CallFail reason provided by the RIL with the result of 963 * RIL_REQUEST_LAST_CALL_FAIL_CAUSE 964 */ getPreciseDisconnectCause()965 public abstract int getPreciseDisconnectCause(); 966 967 /** 968 * Returns the original Connection instance associated with 969 * this Connection 970 */ getOrigConnection()971 public Connection getOrigConnection() { 972 return mOrigConnection; 973 } 974 975 /** 976 * Returns whether the original ImsPhoneConnection was a member 977 * of a conference call 978 * @return valid only when getOrigConnection() is not null 979 */ isMultiparty()980 public abstract boolean isMultiparty(); 981 982 /** 983 * Applicable only for IMS Call. Determines if this call is the origin of the conference call 984 * (i.e. {@code #isConferenceHost()} is {@code true}), or if it is a member of a conference 985 * hosted on another device. 986 * 987 * @return {@code true} if this call is the origin of the conference call it is a member of, 988 * {@code false} otherwise. 989 */ isConferenceHost()990 public boolean isConferenceHost() { 991 return false; 992 } 993 994 /** 995 * Applicable only for IMS Call. Determines if a connection is a member of a conference hosted 996 * on another device. 997 * 998 * @return {@code true} if the connection is a member of a conference hosted on another device. 999 */ isMemberOfPeerConference()1000 public boolean isMemberOfPeerConference() { 1001 return false; 1002 } 1003 migrateFrom(Connection c)1004 public void migrateFrom(Connection c) { 1005 if (c == null) return; 1006 mListeners = c.mListeners; 1007 mDialString = c.getOrigDialString(); 1008 mCreateTime = c.getCreateTime(); 1009 mConnectTime = c.getConnectTime(); 1010 mConnectTimeReal = c.getConnectTimeReal(); 1011 mHoldingStartTime = c.getHoldingStartTime(); 1012 mOrigConnection = c.getOrigConnection(); 1013 mPostDialString = c.mPostDialString; 1014 mNextPostDialChar = c.mNextPostDialChar; 1015 mPostDialState = c.mPostDialState; 1016 1017 // Migrate Emergency call parameters 1018 mIsEmergencyCall = c.isEmergencyCall(); 1019 mEmergencyNumberInfo = c.getEmergencyNumberInfo(); 1020 mHasKnownUserIntentEmergency = c.hasKnownUserIntentEmergency(); 1021 } 1022 1023 /** 1024 * Assign a listener to be notified of state changes. 1025 * 1026 * @param listener A listener. 1027 */ addListener(Listener listener)1028 public void addListener(Listener listener) { 1029 mListeners.add(listener); 1030 } 1031 1032 /** 1033 * Removes a listener. 1034 * 1035 * @param listener A listener. 1036 */ removeListener(Listener listener)1037 public final void removeListener(Listener listener) { 1038 mListeners.remove(listener); 1039 } 1040 1041 /** 1042 * Returns the current video state of the connection. 1043 * 1044 * @return The video state of the connection. 1045 */ getVideoState()1046 public int getVideoState() { 1047 return mVideoState; 1048 } 1049 1050 /** 1051 * Called to get Connection capabilities.Returns Capabilities bitmask. 1052 * @See Connection.Capability. 1053 */ getConnectionCapabilities()1054 public int getConnectionCapabilities() { 1055 return mConnectionCapabilities; 1056 } 1057 1058 /** 1059 * @return {@code} true if the connection has the specified capabilities. 1060 */ hasCapabilities(int connectionCapabilities)1061 public boolean hasCapabilities(int connectionCapabilities) { 1062 return (mConnectionCapabilities & connectionCapabilities) == connectionCapabilities; 1063 } 1064 1065 /** 1066 * Applies a capability to a capabilities bit-mask. 1067 * 1068 * @param capabilities The capabilities bit-mask. 1069 * @param capability The capability to apply. 1070 * @return The capabilities bit-mask with the capability applied. 1071 */ addCapability(int capabilities, int capability)1072 public static int addCapability(int capabilities, int capability) { 1073 return capabilities | capability; 1074 } 1075 1076 /** 1077 * Removes a capability to a capabilities bit-mask. 1078 * 1079 * @param capabilities The capabilities bit-mask. 1080 * @param capability The capability to remove. 1081 * @return The capabilities bit-mask with the capability removed. 1082 */ removeCapability(int capabilities, int capability)1083 public static int removeCapability(int capabilities, int capability) { 1084 return capabilities & ~capability; 1085 } 1086 1087 /** 1088 * Returns whether the connection is using a wifi network. 1089 * 1090 * @return {@code True} if the connection is using a wifi network. 1091 */ isWifi()1092 public boolean isWifi() { 1093 return getCallRadioTech() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; 1094 } 1095 1096 /** 1097 * Returns radio technology is used for the connection. 1098 * 1099 * @return the RIL Voice Radio Technology used for current connection, 1100 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 1101 */ getCallRadioTech()1102 public @RilRadioTechnology int getCallRadioTech() { 1103 return mCallRadioTech; 1104 } 1105 1106 /** 1107 * Returns whether the connection uses voip audio mode 1108 * 1109 * @return {@code True} if the connection uses voip audio mode 1110 */ getAudioModeIsVoip()1111 public boolean getAudioModeIsVoip() { 1112 return mAudioModeIsVoip; 1113 } 1114 1115 /** 1116 * Returns the {@link android.telecom.Connection.VideoProvider} for the connection. 1117 * 1118 * @return The {@link android.telecom.Connection.VideoProvider}. 1119 */ getVideoProvider()1120 public android.telecom.Connection.VideoProvider getVideoProvider() { 1121 return mVideoProvider; 1122 } 1123 1124 /** 1125 * Returns the audio-quality for the connection. 1126 * 1127 * @return The audio quality for the connection. 1128 */ getAudioQuality()1129 public int getAudioQuality() { 1130 return mAudioQuality; 1131 } 1132 1133 1134 /** 1135 * Returns the current call substate of the connection. 1136 * 1137 * @return The call substate of the connection. 1138 */ getCallSubstate()1139 public int getCallSubstate() { 1140 return mCallSubstate; 1141 } 1142 1143 1144 /** 1145 * Sets the videoState for the current connection and reports the changes to all listeners. 1146 * Valid video states are defined in {@link android.telecom.VideoProfile}. 1147 * 1148 * @return The video state. 1149 */ 1150 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setVideoState(int videoState)1151 public void setVideoState(int videoState) { 1152 mVideoState = videoState; 1153 for (Listener l : mListeners) { 1154 l.onVideoStateChanged(mVideoState); 1155 } 1156 } 1157 1158 /** 1159 * Called to set Connection capabilities. This will take Capabilities bitmask as input which is 1160 * converted from Capabilities constants. 1161 * 1162 * @See Connection.Capability. 1163 * @param capabilities The Capabilities bitmask. 1164 */ setConnectionCapabilities(int capabilities)1165 public void setConnectionCapabilities(int capabilities) { 1166 if (mConnectionCapabilities != capabilities) { 1167 mConnectionCapabilities = capabilities; 1168 for (Listener l : mListeners) { 1169 l.onConnectionCapabilitiesChanged(mConnectionCapabilities); 1170 } 1171 } 1172 } 1173 1174 /** 1175 * Sets RIL voice radio technology used for current connection. 1176 * 1177 * @param vrat the RIL voice radio technology for current connection, 1178 * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. 1179 */ setCallRadioTech(@ilRadioTechnology int vrat)1180 public void setCallRadioTech(@RilRadioTechnology int vrat) { 1181 if (mCallRadioTech == vrat) { 1182 return; 1183 } 1184 mCallRadioTech = vrat; 1185 for (Listener l : mListeners) { 1186 l.onCallRadioTechChanged(vrat); 1187 } 1188 } 1189 1190 /** 1191 * Set the voip audio mode for the connection 1192 * 1193 * @param isVoip {@code True} if voip audio mode is being used. 1194 */ setAudioModeIsVoip(boolean isVoip)1195 public void setAudioModeIsVoip(boolean isVoip) { 1196 mAudioModeIsVoip = isVoip; 1197 } 1198 1199 /** 1200 * Set the audio quality for the connection. 1201 * 1202 * @param audioQuality The audio quality. 1203 */ setAudioQuality(int audioQuality)1204 public void setAudioQuality(int audioQuality) { 1205 mAudioQuality = audioQuality; 1206 for (Listener l : mListeners) { 1207 l.onAudioQualityChanged(mAudioQuality); 1208 } 1209 } 1210 1211 /** 1212 * Notifies interested parties of changes to the media attributes of the call. 1213 */ notifyMediaAttributesChanged()1214 public void notifyMediaAttributesChanged() { 1215 for (Listener l: mListeners) { 1216 l.onMediaAttributesChanged(); 1217 } 1218 } 1219 1220 /** 1221 * Notifies listeners that connection extras has changed. 1222 * @param extras New connection extras. This Bundle will be cloned to ensure that any concurrent 1223 * modifications to the extras Bundle do not affect Bundle operations in the onExtrasChanged 1224 * listeners. 1225 */ setConnectionExtras(Bundle extras)1226 public void setConnectionExtras(Bundle extras) { 1227 if (extras != null) { 1228 mExtras = new Bundle(extras); 1229 1230 int previousCount = mExtras.size(); 1231 // Prevent vendors from passing in extras other than primitive types and android API 1232 // parcelables. 1233 mExtras = TelephonyUtils.filterValues(mExtras); 1234 int filteredCount = mExtras.size(); 1235 if (filteredCount != previousCount) { 1236 Rlog.i(TAG, "setConnectionExtras: filtering " + (previousCount - filteredCount) 1237 + " invalid extras."); 1238 } 1239 } else { 1240 mExtras = null; 1241 } 1242 1243 for (Listener l : mListeners) { 1244 l.onExtrasChanged(mExtras); 1245 } 1246 } 1247 1248 /** 1249 * Retrieves the current connection extras. 1250 * @return the connection extras. 1251 */ getConnectionExtras()1252 public Bundle getConnectionExtras() { 1253 return mExtras == null ? null : new Bundle(mExtras); 1254 } 1255 1256 /** 1257 * @return {@code true} if answering the call will cause the current active call to be 1258 * disconnected, {@code false} otherwise. 1259 */ isActiveCallDisconnectedOnAnswer()1260 public boolean isActiveCallDisconnectedOnAnswer() { 1261 return mAnsweringDisconnectsActiveCall; 1262 } 1263 1264 /** 1265 * Sets whether answering this call will cause the active call to be disconnected. 1266 * <p> 1267 * Should only be set {@code true} if there is an active call and this call is ringing. 1268 * 1269 * @param answeringDisconnectsActiveCall {@code true} if answering the call will call the active 1270 * call to be disconnected. 1271 */ setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall)1272 public void setActiveCallDisconnectedOnAnswer(boolean answeringDisconnectsActiveCall) { 1273 mAnsweringDisconnectsActiveCall = answeringDisconnectsActiveCall; 1274 } 1275 shouldAllowAddCallDuringVideoCall()1276 public boolean shouldAllowAddCallDuringVideoCall() { 1277 return mAllowAddCallDuringVideoCall; 1278 } 1279 setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall)1280 public void setAllowAddCallDuringVideoCall(boolean allowAddCallDuringVideoCall) { 1281 mAllowAddCallDuringVideoCall = allowAddCallDuringVideoCall; 1282 } 1283 shouldAllowHoldingVideoCall()1284 public boolean shouldAllowHoldingVideoCall() { 1285 return mAllowHoldingVideoCall; 1286 } 1287 setAllowHoldingVideoCall(boolean allowHoldingVideoCall)1288 public void setAllowHoldingVideoCall(boolean allowHoldingVideoCall) { 1289 mAllowHoldingVideoCall = allowHoldingVideoCall; 1290 } 1291 1292 /** 1293 * Sets whether the connection is the result of an external call which was pulled to the local 1294 * device. 1295 * 1296 * @param isPulledCall {@code true} if this connection is the result of pulling an external call 1297 * to the local device. 1298 */ setIsPulledCall(boolean isPulledCall)1299 public void setIsPulledCall(boolean isPulledCall) { 1300 mIsPulledCall = isPulledCall; 1301 } 1302 isPulledCall()1303 public boolean isPulledCall() { 1304 return mIsPulledCall; 1305 } 1306 1307 /** 1308 * For an external call which is being pulled (e.g. {@link #isPulledCall()} is {@code true}), 1309 * sets the dialog Id for the external call. Used to handle failures to pull a call so that the 1310 * pulled call can be reconciled with its original external connection. 1311 * 1312 * @param pulledDialogId The dialog id associated with a pulled call. 1313 */ setPulledDialogId(int pulledDialogId)1314 public void setPulledDialogId(int pulledDialogId) { 1315 mPulledDialogId = pulledDialogId; 1316 } 1317 getPulledDialogId()1318 public int getPulledDialogId() { 1319 return mPulledDialogId; 1320 } 1321 1322 /** 1323 * Sets the call substate for the current connection and reports the changes to all listeners. 1324 * Valid call substates are defined in {@link android.telecom.Connection}. 1325 * 1326 * @return The call substate. 1327 */ setCallSubstate(int callSubstate)1328 public void setCallSubstate(int callSubstate) { 1329 mCallSubstate = callSubstate; 1330 for (Listener l : mListeners) { 1331 l.onCallSubstateChanged(mCallSubstate); 1332 } 1333 } 1334 1335 /** 1336 * Sets the {@link android.telecom.Connection.VideoProvider} for the connection. 1337 * 1338 * @param videoProvider The video call provider. 1339 */ setVideoProvider(android.telecom.Connection.VideoProvider videoProvider)1340 public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 1341 mVideoProvider = videoProvider; 1342 for (Listener l : mListeners) { 1343 l.onVideoProviderChanged(mVideoProvider); 1344 } 1345 } 1346 1347 /** 1348 * {@link CallTracker#convertNumberIfNecessary(Phone, String)} can be used to convert a dialed 1349 * number to another number based on carrier config. This is used where a carrier wishes to 1350 * redirect certain short codes such as *55 to another number (e.g. a 1-800 service number). 1351 * The {@link CallTracker} sub-classes call 1352 * {@link CallTracker#convertNumberIfNecessary(Phone, String)} to retrieve the newly converted 1353 * number and instantiate the {@link Connection} instance using the converted number so that the 1354 * system will dial out the substitution number instead of the originally dialed one. This gem 1355 * of a method is called after the dialing process to restore the originally dialed number and 1356 * keep track of the fact that a converted number was used to place the call. 1357 * @param oriNumber The original number prior to conversion. 1358 */ restoreDialedNumberAfterConversion(String oriNumber)1359 public void restoreDialedNumberAfterConversion(String oriNumber) { 1360 mNumberConverted = true; 1361 mConvertedNumber = mAddress; 1362 mAddress = oriNumber; 1363 mDialString = oriNumber; 1364 } 1365 1366 /** 1367 * Changes the address and presentation for this call. 1368 * @param newAddress The new address. 1369 * @param numberPresentation The number presentation for the address. 1370 */ setAddress(String newAddress, int numberPresentation)1371 public void setAddress(String newAddress, int numberPresentation) { 1372 Rlog.i(TAG, "setAddress = " + newAddress); 1373 mAddress = newAddress; 1374 mNumberPresentation = numberPresentation; 1375 } 1376 setDialString(String newDialString)1377 public void setDialString(String newDialString) { 1378 mDialString = newDialString; 1379 } 1380 1381 /** 1382 * Notifies listeners of a change to conference participant(s). 1383 * 1384 * @param conferenceParticipants The participant(s). 1385 */ updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants)1386 public void updateConferenceParticipants(List<ConferenceParticipant> conferenceParticipants) { 1387 for (Listener l : mListeners) { 1388 l.onConferenceParticipantsChanged(conferenceParticipants); 1389 } 1390 } 1391 1392 /** 1393 * Notifies listeners of a change to the multiparty state of the connection. 1394 * 1395 * @param isMultiparty The participant(s). 1396 */ updateMultipartyState(boolean isMultiparty)1397 public void updateMultipartyState(boolean isMultiparty) { 1398 for (Listener l : mListeners) { 1399 l.onMultipartyStateChanged(isMultiparty); 1400 } 1401 } 1402 1403 /** 1404 * Notifies listeners of a failure in merging this connection with the background connection. 1405 */ onConferenceMergeFailed()1406 public void onConferenceMergeFailed() { 1407 for (Listener l : mListeners) { 1408 l.onConferenceMergedFailed(); 1409 } 1410 } 1411 1412 /** 1413 * Notifies that the underlying phone has exited ECM mode. 1414 */ onExitedEcmMode()1415 public void onExitedEcmMode() { 1416 for (Listener l : mListeners) { 1417 l.onExitedEcmMode(); 1418 } 1419 } 1420 1421 /** 1422 * Notifies the connection that a call to {@link #pullExternalCall()} has failed to pull the 1423 * call to the local device. 1424 * 1425 * @param externalConnection The original 1426 * {@link com.android.internal.telephony.imsphone.ImsExternalConnection} from which the 1427 * pull was initiated. 1428 */ onCallPullFailed(Connection externalConnection)1429 public void onCallPullFailed(Connection externalConnection) { 1430 for (Listener l : mListeners) { 1431 l.onCallPullFailed(externalConnection); 1432 } 1433 } 1434 onOriginalConnectionReplaced(Connection newConnection)1435 public void onOriginalConnectionReplaced(Connection newConnection) { 1436 for (Listener l : mListeners) { 1437 l.onOriginalConnectionReplaced(newConnection); 1438 } 1439 } 1440 /** 1441 * Notifies the connection that there was a failure while handing over to WIFI. 1442 */ onHandoverToWifiFailed()1443 public void onHandoverToWifiFailed() { 1444 for (Listener l : mListeners) { 1445 l.onHandoverToWifiFailed(); 1446 } 1447 } 1448 1449 /** 1450 * Notifies the connection of a connection event. 1451 */ onConnectionEvent(String event, Bundle extras)1452 public void onConnectionEvent(String event, Bundle extras) { 1453 for (Listener l : mListeners) { 1454 l.onConnectionEvent(event, extras); 1455 } 1456 } 1457 1458 /** 1459 * Notifies this Connection of a request to disconnect a participant of the conference managed 1460 * by the connection. 1461 * 1462 * @param endpoint the {@link Uri} of the participant to disconnect. 1463 */ onDisconnectConferenceParticipant(Uri endpoint)1464 public void onDisconnectConferenceParticipant(Uri endpoint) { 1465 } 1466 1467 /** 1468 * Called by a {@link android.telecom.Connection} to indicate that this call should be pulled 1469 * to the local device. 1470 */ pullExternalCall()1471 public void pullExternalCall() { 1472 } 1473 onRttModifyRequestReceived()1474 public void onRttModifyRequestReceived() { 1475 for (Listener l : mListeners) { 1476 l.onRttModifyRequestReceived(); 1477 } 1478 } 1479 onRttModifyResponseReceived(int status)1480 public void onRttModifyResponseReceived(int status) { 1481 for (Listener l : mListeners) { 1482 l.onRttModifyResponseReceived(status); 1483 } 1484 } 1485 onRttInitiated()1486 public void onRttInitiated() { 1487 for (Listener l : mListeners) { 1488 l.onRttInitiated(); 1489 } 1490 } 1491 onRttTerminated()1492 public void onRttTerminated() { 1493 for (Listener l : mListeners) { 1494 l.onRttTerminated(); 1495 } 1496 } 1497 /** 1498 * Notify interested parties that this connection disconnected. 1499 * {@code TelephonyConnection}, for example, uses this. 1500 * @param reason the disconnect code, per {@link DisconnectCause}. 1501 */ notifyDisconnect(int reason)1502 protected void notifyDisconnect(int reason) { 1503 Rlog.i(TAG, "notifyDisconnect: callId=" + getTelecomCallId() + ", reason=" + reason); 1504 for (Listener l : mListeners) { 1505 l.onDisconnect(reason); 1506 } 1507 } 1508 1509 /** 1510 * 1511 */ getPhoneType()1512 public int getPhoneType() { 1513 return mPhoneType; 1514 } 1515 1516 /** 1517 * Reset the Connection time and Duration 1518 */ resetConnectionTime()1519 public void resetConnectionTime() { 1520 if (mPhoneType == PhoneConstants.PHONE_TYPE_CDMA_LTE || 1521 mPhoneType == PhoneConstants.PHONE_TYPE_CDMA) { 1522 mConnectTime = System.currentTimeMillis(); 1523 mConnectTimeReal = SystemClock.elapsedRealtime(); 1524 mDuration = 0; 1525 } 1526 } 1527 1528 /** 1529 * Sets whether this {@link Connection} has been identified by the network as an emergency call. 1530 * @param isNetworkIdentifiedEmergencyCall {@code true} if ecall, {@code false} otherwise. 1531 */ setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall)1532 public void setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall) { 1533 mIsNetworkIdentifiedEmergencyCall = isNetworkIdentifiedEmergencyCall; 1534 for (Listener l : mListeners) { 1535 l.onIsNetworkEmergencyCallChanged(isNetworkIdentifiedEmergencyCall); 1536 } 1537 } 1538 1539 /** 1540 * @return Whether this {@link Connection} has been identified by the network as an emergency 1541 * call. 1542 */ isNetworkIdentifiedEmergencyCall()1543 public boolean isNetworkIdentifiedEmergencyCall() { 1544 return mIsNetworkIdentifiedEmergencyCall; 1545 } 1546 1547 /** 1548 * Build a human representation of a connection instance, suitable for debugging. 1549 * Don't log personal stuff unless in debug mode. 1550 * @return a string representing the internal state of this connection. 1551 */ toString()1552 public String toString() { 1553 StringBuilder str = new StringBuilder(128); 1554 1555 str.append(" callId: " + getTelecomCallId()); 1556 str.append(" objId: " + System.identityHashCode(this)); 1557 str.append(" isExternal: " + (((mConnectionCapabilities & Capability.IS_EXTERNAL_CONNECTION) 1558 == Capability.IS_EXTERNAL_CONNECTION) ? "Y" : "N")); 1559 if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) { 1560 str.append("addr: " + getAddress()) 1561 .append(" pres.: " + getNumberPresentation()) 1562 .append(" dial: " + getOrigDialString()) 1563 .append(" postdial: " + getRemainingPostDialString()) 1564 .append(" cnap name: " + getCnapName()) 1565 .append("(" + getCnapNamePresentation() + ")"); 1566 } 1567 str.append(" incoming: " + isIncoming()) 1568 .append(" state: " + getState()) 1569 .append(" post dial state: " + getPostDialState()); 1570 return str.toString(); 1571 } 1572 1573 /** 1574 * Get current audio codec. 1575 * @return current audio codec. 1576 */ getAudioCodec()1577 public int getAudioCodec() { 1578 return mAudioCodec; 1579 } 1580 1581 /** 1582 * @return the audio codec bitrate in kbps. 1583 */ getAudioCodecBitrateKbps()1584 public float getAudioCodecBitrateKbps() { 1585 return mAudioCodecBitrateKbps; 1586 } 1587 1588 /** 1589 * @return the audio codec bandwidth in kHz. 1590 */ getAudioCodecBandwidthKhz()1591 public float getAudioCodecBandwidthKhz() { 1592 return mAudioCodecBandwidthKhz; 1593 } 1594 1595 /** 1596 * @return The number verification status; only applicable for IMS calls. 1597 */ getNumberVerificationStatus()1598 public @android.telecom.Connection.VerificationStatus int getNumberVerificationStatus() { 1599 return mNumberVerificationStatus; 1600 } 1601 1602 /** 1603 * Sets the number verification status. 1604 * @param verificationStatus The new verification status 1605 */ setNumberVerificationStatus( @ndroid.telecom.Connection.VerificationStatus int verificationStatus)1606 public void setNumberVerificationStatus( 1607 @android.telecom.Connection.VerificationStatus int verificationStatus) { 1608 mNumberVerificationStatus = verificationStatus; 1609 } 1610 1611 /** 1612 * Called to report a DTMF digit received from the network. 1613 * @param digit the received digit. 1614 */ receivedDtmfDigit(char digit)1615 public void receivedDtmfDigit(char digit) { 1616 for (Listener l : mListeners) { 1617 l.onReceivedDtmfDigit(digit); 1618 } 1619 } 1620 1621 /** 1622 * Called to report audio mode changed for Voip. 1623 * @param imsAudioHandler the received value to handle the audio for this IMS call. 1624 */ onAudioModeIsVoipChanged(@msAudioHandler int imsAudioHandler)1625 public void onAudioModeIsVoipChanged(@ImsAudioHandler int imsAudioHandler) { 1626 Rlog.i(TAG, "onAudioModeIsVoipChanged: conn imsAudioHandler " + imsAudioHandler); 1627 1628 boolean isVoip = imsAudioHandler == MmTelFeature.AUDIO_HANDLER_ANDROID; 1629 if (isVoip == mAudioModeIsVoip) return; 1630 mAudioModeIsVoip = isVoip; 1631 1632 Rlog.i(TAG, "onAudioModeIsVoipChanged: isVoip: " + isVoip 1633 + "mAudioModeIsVoip:" + mAudioModeIsVoip); 1634 1635 for (Listener l : mListeners) { 1636 l.onAudioModeIsVoipChanged(imsAudioHandler); 1637 } 1638 } 1639 1640 /** 1641 * Called to report RTP header extensions received from the network. 1642 * @param extensionData the received extension data. 1643 */ receivedRtpHeaderExtensions(@onNull Set<RtpHeaderExtension> extensionData)1644 public void receivedRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> extensionData) { 1645 for (Listener l : mListeners) { 1646 l.onReceivedRtpHeaderExtensions(extensionData); 1647 } 1648 } 1649 } 1650