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