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