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