• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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