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