• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 android.telephony.ims;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.annotation.TestApi;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.os.Build;
26 import android.os.Bundle;
27 import android.os.Parcel;
28 import android.os.Parcelable;
29 import android.telecom.VideoProfile;
30 import android.telephony.emergency.EmergencyNumber;
31 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
32 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
33 import android.telephony.ims.feature.MmTelFeature;
34 import android.util.ArraySet;
35 import android.util.Log;
36 
37 import com.android.internal.annotations.VisibleForTesting;
38 import com.android.internal.telephony.PhoneConstants;
39 import com.android.internal.telephony.util.TelephonyUtils;
40 
41 import java.lang.annotation.Retention;
42 import java.lang.annotation.RetentionPolicy;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.List;
46 import java.util.Set;
47 import java.util.stream.Collectors;
48 
49 /**
50  * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
51  * additional information related to the call.
52  * <p>
53  * See the following specifications for more information about this class: GSMA IR.92/IR.94,
54  * 3GPP TS 24.229/TS 26.114/TS26.111.
55  * @hide
56  */
57 @SystemApi
58 public final class ImsCallProfile implements Parcelable {
59     private static final String TAG = "ImsCallProfile";
60 
61     /**
62      * Service types
63      */
64     /**
65      * It is for a special case. It helps that the application can make a call
66      * without IMS connection (not registered).
67      * In the moment of the call initiation, the device try to connect to the IMS network
68      * and initiates the call.
69      */
70     public static final int SERVICE_TYPE_NONE = 0;
71     /**
72      * It is a default type and can be selected when the device is connected to the IMS network.
73      */
74     public static final int SERVICE_TYPE_NORMAL = 1;
75     /**
76      * It is for an emergency call.
77      */
78     public static final int SERVICE_TYPE_EMERGENCY = 2;
79 
80     /**
81      * Call types
82      */
83     /**
84      * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
85      */
86     public static final int CALL_TYPE_VOICE_N_VIDEO = 1;
87     /**
88      * IR.92 (Voice only)
89      */
90     public static final int CALL_TYPE_VOICE = 2;
91     /**
92      * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade)
93      */
94     public static final int CALL_TYPE_VIDEO_N_VOICE = 3;
95     /**
96      * Video Telephony (audio / video two way)
97      */
98     public static final int CALL_TYPE_VT = 4;
99     /**
100      * Video Telephony (audio two way / video TX one way)
101      */
102     public static final int CALL_TYPE_VT_TX = 5;
103     /**
104      * Video Telephony (audio two way / video RX one way)
105      */
106     public static final int CALL_TYPE_VT_RX = 6;
107     /**
108      * Video Telephony (audio two way / video inactive)
109      */
110     public static final int CALL_TYPE_VT_NODIR = 7;
111     /**
112      * VideoShare (video two way)
113      */
114     public static final int CALL_TYPE_VS = 8;
115     /**
116      * VideoShare (video TX one way)
117      */
118     public static final int CALL_TYPE_VS_TX = 9;
119     /**
120      * VideoShare (video RX one way)
121      */
122     public static final int CALL_TYPE_VS_RX = 10;
123 
124     /**
125      * Extra properties for IMS call.
126      */
127     /**
128      * Boolean extra properties - "true" / "false"
129      *  conference : Indicates if the session is for the conference call or not.
130      *  e_call : Indicates if the session is for the emergency call or not.
131      *  vms : Indicates if the session is connected to the voice mail system or not.
132      *  call_mode_changeable : Indicates if the session is able to upgrade/downgrade
133      *      the video during voice call.
134      *  conference_avail : Indicates if the session can be extended to the conference.
135      */
136 
137     /**
138      * Indicates if the session is for a conference call or not. If not defined, should be
139      * considered {@code false}.
140      * Boolean extra properties - {@code true} / {@code false}.
141      *
142      * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
143      * @hide
144      */
145     @SystemApi
146     public static final String EXTRA_CONFERENCE = "android.telephony.ims.extra.CONFERENCE";
147 
148     /**
149      * The previous string of EXTRA_CONFERENCE. Use EXTRA_CONFERENCE whenever possible.
150      * For external app or vendor code backward compatibility, we should always set value for both
151      * EXTRA_CONFERENCE_DEPRECATED and EXTRA_CONFERENCE.
152      *
153      * @deprecated Remove when not needed anymore.
154      *
155      * @hide
156      */
157     public static final String EXTRA_CONFERENCE_DEPRECATED = "conference";
158 
159     /**
160      * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an
161      * emergency call.  The {@link ImsService} sets this on a call to indicate that the network has
162      * identified the call as an emergency call.
163      */
164     public static final String EXTRA_EMERGENCY_CALL = "e_call";
165 
166     /**
167      * @hide
168      */
169     public static final String EXTRA_VMS = "vms";
170     /**
171      * @hide
172      */
173     public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";
174 
175     /**
176      * Indicates if the session can be extended to a conference call. If not defined, should be
177      * considered {@code false}.
178      * Boolean extra properties - {@code true} / {@code false}.
179      *
180      * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
181      * @hide
182      */
183     @SystemApi
184     public static final String EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED =
185             "android.telephony.ims.extra.EXTENDING_TO_CONFERENCE_SUPPORTED";
186 
187     /**
188      * The previous string of EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED.
189      * Use EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED whenever possible.
190      * For backward compatibility, we should always set value for both
191      * EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED and EXTRA_CONFERENCE_AVAIL.
192      *
193      * @deprecated Remove when not needed anymore.
194      *
195      * @hide
196      */
197     public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
198 
199     /**
200      * Extra key used to store a Bundle containing proprietary extras to send to the ImsService.
201      * Use {@link #getProprietaryCallExtras()} instead.
202      * @hide
203      */
204     @TestApi
205     public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
206 
207     /**
208      * Rule for originating identity (number) presentation, MO/MT.
209      *      {@link ImsCallProfile#OIR_DEFAULT}
210      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
211      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
212      */
213     public static final String EXTRA_OIR = "oir";
214     /**
215      * Rule for calling name presentation
216      *      {@link ImsCallProfile#OIR_DEFAULT}
217      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
218      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
219      */
220     public static final String EXTRA_CNAP = "cnap";
221     /**
222      * To identify the Ims call type, MO
223      *      {@link ImsCallProfile#DIALSTRING_NORMAL}
224      *      {@link ImsCallProfile#DIALSTRING_SS_CONF}
225      *      {@link ImsCallProfile#DIALSTRING_USSD}
226      */
227     public static final String EXTRA_DIALSTRING = "dialstring";
228     /**
229      * This extra holds call fail cause because of which redial is attempted.
230      * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*}
231      * for possible values this extra can hold.
232      *
233      * @hide
234      */
235     public static final String EXTRA_RETRY_CALL_FAIL_REASON =
236             "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON";
237     /**
238      * This extra holds call network type on which lower layers
239      * may try attempting redial.
240      * See {@link TelephonyManager} {@code NETWORK_TYPE_*}
241      * for possible values this extra can hold.
242      *
243      * @hide
244      */
245     public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE =
246             "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE";
247 
248     /**
249      * Extra for the call composer call priority, either {@link ImsCallProfile#PRIORITY_NORMAL} or
250      * {@link ImsCallProfile#PRIORITY_URGENT}. It can be set via
251      * {@link #setCallExtraInt(String, int)}.
252      *
253      * Reference: RCC.20 Section 2.4.4.2
254      */
255     public static final String EXTRA_PRIORITY = "android.telephony.ims.extra.PRIORITY";
256 
257     // TODO(hallliu) remove the reference to the maximum length and update it later.
258     /**
259      * Extra for the call composer call subject, a string of maximum length 60 characters.
260      * It can be set via {@link #setCallExtra(String, String)}.
261      *
262      * Reference: RCC.20 Section 2.4.3.2
263      */
264     public static final String EXTRA_CALL_SUBJECT = "android.telephony.ims.extra.CALL_SUBJECT";
265 
266     /**
267      * Extra for the call composer call location, an {@Link android.location.Location} parcelable
268      * class to represent the geolocation as a latitude and longitude pair. It can be set via
269      * {@link #setCallExtraParcelable(String, Parcelable)}.
270      *
271      * Reference: RCC.20 Section 2.4.3.2
272      */
273     public static final String EXTRA_LOCATION = "android.telephony.ims.extra.LOCATION";
274 
275     /**
276      * Extra for the call composer picture URL, a String that indicates the URL on the carrier’s
277      * server infrastructure to get the picture. It can be set via
278      * {@link #setCallExtra(String, String)}.
279      *
280      * Note that this URL is not intended to be parsed by the IMS stack -- it should be sent
281      * directly to the network for consumption by the called party or forwarded directly from the
282      * network to the platform for caching and download.
283      *
284      * Reference: RCC.20 Section 2.4.3.2
285      */
286     public static final String EXTRA_PICTURE_URL = "android.telephony.ims.extra.PICTURE_URL";
287 
288     /**
289      * Boolean extra indicating whether the call is a business call.
290      *
291      * This extra will be set to {@code true} if and only if the SIP INVITE headers contain the
292      * "Organization" header.
293      */
294     public static final String EXTRA_IS_BUSINESS_CALL =
295             "android.telephony.ims.extra.IS_BUSINESS_CALL";
296 
297     /**
298      * Values for EXTRA_OIR / EXTRA_CNAP
299      */
300     /**
301      * Default presentation for Originating Identity.
302      */
303     public static final int OIR_DEFAULT = 0;    // "user subscription default value"
304     /**
305      * Restricted presentation for Originating Identity.
306      */
307     public static final int OIR_PRESENTATION_RESTRICTED = 1;
308     /**
309      * Not restricted presentation for Originating Identity.
310      */
311     public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
312     /**
313      * Presentation unknown for Originating Identity.
314      */
315     public static final int OIR_PRESENTATION_UNKNOWN = 3;
316     /**
317      * Payphone presentation for Originating Identity.
318      */
319     public static final int OIR_PRESENTATION_PAYPHONE = 4;
320 
321     //Values for EXTRA_DIALSTRING
322     /**
323      * A default or normal normal call.
324      */
325     public static final int DIALSTRING_NORMAL = 0;
326     /**
327      * Call for SIP-based user configuration
328      */
329     public static final int DIALSTRING_SS_CONF = 1;
330     /**
331      * Call for USSD message
332      */
333     public static final int DIALSTRING_USSD = 2;
334 
335     // Values for EXTRA_PRIORITY
336     /**
337      * Indicates the call composer call priority is normal.
338      *
339      * Reference: RCC.20 Section 2.4.4.2
340      */
341     public static final int PRIORITY_NORMAL = 0;
342 
343     /**
344      * Indicates the call composer call priority is urgent.
345      *
346      * Reference: RCC.20 Section 2.4.4.2
347      */
348     public static final int PRIORITY_URGENT = 1;
349 
350     /**
351      * Call is not restricted on peer side and High Definition media is supported
352      */
353     public static final int CALL_RESTRICT_CAUSE_NONE = 0;
354 
355     /**
356      * High Definition media is not supported on the peer side due to the Radio Access Technology
357      * (RAT) it is are connected to.
358      */
359     public static final int CALL_RESTRICT_CAUSE_RAT = 1;
360 
361     /**
362      * The service has been disabled on the peer side.
363      */
364     public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
365 
366     /**
367      * High definition media is not currently supported.
368      */
369     public static final int CALL_RESTRICT_CAUSE_HD = 3;
370 
371     /**@hide*/
372     @Retention(RetentionPolicy.SOURCE)
373     @IntDef(prefix = "CALL_RESTRICT_CAUSE_", value = {
374             CALL_RESTRICT_CAUSE_NONE,
375             CALL_RESTRICT_CAUSE_RAT,
376             CALL_RESTRICT_CAUSE_DISABLED,
377             CALL_RESTRICT_CAUSE_HD
378     })
379     public @interface CallRestrictCause {}
380 
381     /**
382      * String extra properties
383      *  oi : Originating identity (number), MT only
384      *  cna : Calling name
385      *  ussd : For network-initiated USSD, MT only
386      *  remote_uri : Connected user identity (it can be used for the conference)
387      *  ChildNum: Child number info.
388      *  Codec: Codec info.
389      *  DisplayText: Display text for the call.
390      *  AdditionalCallInfo: Additional call info.
391      *  CallPull: Boolean value specifying if the call is a pulled call.
392      */
393     public static final String EXTRA_OI = "oi";
394     public static final String EXTRA_CNA = "cna";
395     public static final String EXTRA_USSD = "ussd";
396     public static final String EXTRA_REMOTE_URI = "remote_uri";
397     public static final String EXTRA_CHILD_NUMBER = "ChildNum";
398     public static final String EXTRA_CODEC = "Codec";
399     public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
400     public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
401     public static final String EXTRA_IS_CALL_PULL = "CallPull";
402 
403     /**
404      * String extra property
405      *  Containing fields from the SIP INVITE message for an IMS call
406      */
407     public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS =
408                                   "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
409 
410     /**
411      * CallDisconnectCause: Specify call disconnect cause. This extra should be a code
412      * corresponding to ImsReasonInfo and should only be populated in the case that the
413      * call has already been missed
414      */
415     public static final String EXTRA_CALL_DISCONNECT_CAUSE =
416                                  "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
417 
418     /**
419      * Extra key which the RIL can use to indicate the radio technology used for a call.
420      * Valid values are:
421      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
422      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
423      * {@code RIL_RADIO_TECHNOLOGY_*} constants.
424      * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
425      * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
426      * "14" vs (int) 14).
427      * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
428      *      updateImsCallRatFromExtras(Bundle)} to determine whether to set the
429      * {@link android.telecom.TelecomManager#EXTRA_CALL_NETWORK_TYPE} extra value and
430      * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
431      * @deprecated the constants associated with this extra are hidden, instead use
432      * {@link #EXTRA_CALL_NETWORK_TYPE}.
433      */
434     @Deprecated
435     public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
436 
437     /**
438      * Extra key with an {@code int} value which can be set in {@link #setCallExtraInt(String, int)}
439      * to indicate the network type used for a call.
440      * <p>
441      * Valid values are defined by {@code TelephonyManager.NETWORK_TYPE_*} constants. An example may
442      * be {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}.
443      */
444     public static final String EXTRA_CALL_NETWORK_TYPE =
445             "android.telephony.ims.extra.CALL_NETWORK_TYPE";
446 
447     /**
448      * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'.  Used to ensure
449      * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE}
450      * extra key.  Should be removed when the non-compliant modems are fixed.
451      * @hide
452      * @deprecated Use {@link #EXTRA_CALL_NETWORK_TYPE} instead.
453      */
454     @Deprecated
455     public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech";
456 
457     /**
458      * String extra property containing forwarded numbers associated with the current connection
459      * for an IMS call. The value is string array, and it can include multiple numbers, and
460      * the array values are expected E164 (e.g. +1 (650) 253-0000) format.
461      */
462     public static final String EXTRA_FORWARDED_NUMBER =
463             "android.telephony.ims.extra.FORWARDED_NUMBER";
464 
465     /**
466      * Extra key with an {@code boolean} value which can be set in
467      * {@link #setCallExtraBoolean(String, boolean)} to indicate whether call is a cross sim call.
468      * <p>
469      * Valid values are true if call is cross sim call else false.
470      */
471     public static final String EXTRA_IS_CROSS_SIM_CALL =
472             "android.telephony.ims.extra.IS_CROSS_SIM_CALL";
473 
474     /** @hide */
475     public int mServiceType;
476     /** @hide */
477     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
478     public int mCallType;
479     /** @hide */
480     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
481     public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
482 
483     /**
484      * The VERSTAT for an incoming call's phone number.
485      */
486     private @VerificationStatus int mCallerNumberVerificationStatus;
487 
488     /**
489      * Indicates that the network could not perform verification.
490      */
491     public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0;
492 
493     /**
494      * Indicates that verification by the network passed.  This indicates there is a high likelihood
495      * that the call originated from a valid source.
496      */
497     public static final int VERIFICATION_STATUS_PASSED = 1;
498 
499     /**
500      * Indicates that verification by the network failed.  This indicates there is a high likelihood
501      * that the call did not originate from a valid source.
502      */
503     public static final int VERIFICATION_STATUS_FAILED = 2;
504 
505     /**@hide*/
506     @Retention(RetentionPolicy.SOURCE)
507     @IntDef(prefix = "VERIFICATION_STATUS_", value = {
508             VERIFICATION_STATUS_NOT_VERIFIED,
509             VERIFICATION_STATUS_PASSED,
510             VERIFICATION_STATUS_FAILED
511     })
512     public @interface VerificationStatus {}
513 
514     /**
515      * The emergency service categories, only valid if {@link #getServiceType} returns
516      * {@link #SERVICE_TYPE_EMERGENCY}
517      *
518      * If valid, the value is the bitwise-OR combination of the following constants:
519      * <ol>
520      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
521      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
522      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
523      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
524      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
525      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
526      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
527      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
528      * </ol>
529      *
530      * Reference: 3gpp 23.167, Section 6 - Functional description;
531      *            3gpp 22.101, Section 10 - Emergency Calls.
532      */
533     private @EmergencyServiceCategories int mEmergencyServiceCategories =
534             EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
535 
536     /**
537      * The emergency Uniform Resource Names (URN), only valid if {@link #getServiceType} returns
538      * {@link #SERVICE_TYPE_EMERGENCY}.
539      *
540      * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
541      *            3gpp 22.101, Section 10 - Emergency Calls.
542      */
543     private List<String> mEmergencyUrns = new ArrayList<>();
544 
545     /**
546      * The emergency call routing, only valid if {@link #getServiceType} returns
547      * {@link #SERVICE_TYPE_EMERGENCY}
548      *
549      * If valid, the value is any of the following constants:
550      * <ol>
551      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
552      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
553      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
554      * </ol>
555      */
556     private @EmergencyCallRouting int mEmergencyCallRouting =
557             EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
558 
559     /** Indicates if the call is for testing purpose */
560     private boolean mEmergencyCallTesting = false;
561 
562     /** Indicates if we have known the intent of the user for the call is emergency */
563     private boolean mHasKnownUserIntentEmergency = false;
564 
565     private Set<RtpHeaderExtensionType> mAcceptedRtpHeaderExtensionTypes = new ArraySet<>();
566 
567     /**
568      * Extras associated with this {@link ImsCallProfile}.
569      * <p>
570      * Valid data types include:
571      * <ul>
572      *     <li>{@link Integer} (and int)</li>
573      *     <li>{@link Long} (and long)</li>
574      *     <li>{@link Double} (and double)</li>
575      *     <li>{@link String}</li>
576      *     <li>{@code int[]}</li>
577      *     <li>{@code long[]}</li>
578      *     <li>{@code double[]}</li>
579      *     <li>{@code String[]}</li>
580      *     <li>{@link android.os.PersistableBundle}</li>
581      *     <li>{@link Boolean} (and boolean)</li>
582      *     <li>{@code boolean[]}</li>
583      *     <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
584      * </ul>
585      * <p>
586      * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across
587      * a {@link android.os.Binder}.
588      */
589     /** @hide */
590     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
591     public Bundle mCallExtras;
592     /** @hide */
593     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
594     public ImsStreamMediaProfile mMediaProfile;
595 
596     /** @hide */
ImsCallProfile(Parcel in)597     public ImsCallProfile(Parcel in) {
598         readFromParcel(in);
599     }
600 
601     /**
602      * Default Constructor that initializes the call profile with service type
603      * {@link #SERVICE_TYPE_NORMAL} and call type {@link #CALL_TYPE_VIDEO_N_VOICE}
604      */
ImsCallProfile()605     public ImsCallProfile() {
606         mServiceType = SERVICE_TYPE_NORMAL;
607         mCallType = CALL_TYPE_VOICE_N_VIDEO;
608         mCallExtras = new Bundle();
609         mMediaProfile = new ImsStreamMediaProfile();
610     }
611 
612     /**
613      * Constructor.
614      *
615      * @param serviceType the service type for the call. Can be one of the following:
616      *                    {@link #SERVICE_TYPE_NONE},
617      *                    {@link #SERVICE_TYPE_NORMAL},
618      *                    {@link #SERVICE_TYPE_EMERGENCY}
619      * @param callType the call type. Can be one of the following:
620      *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
621      *                 {@link #CALL_TYPE_VOICE},
622      *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
623      *                 {@link #CALL_TYPE_VT},
624      *                 {@link #CALL_TYPE_VT_TX},
625      *                 {@link #CALL_TYPE_VT_RX},
626      *                 {@link #CALL_TYPE_VT_NODIR},
627      *                 {@link #CALL_TYPE_VS},
628      *                 {@link #CALL_TYPE_VS_TX},
629      *                 {@link #CALL_TYPE_VS_RX}
630      */
ImsCallProfile(int serviceType, int callType)631     public ImsCallProfile(int serviceType, int callType) {
632         mServiceType = serviceType;
633         mCallType = callType;
634         mCallExtras = new Bundle();
635         mMediaProfile = new ImsStreamMediaProfile();
636     }
637 
638     /**
639      * Constructor.
640      *
641      * @param serviceType the service type for the call. Can be one of the following:
642      *                    {@link #SERVICE_TYPE_NONE},
643      *                    {@link #SERVICE_TYPE_NORMAL},
644      *                    {@link #SERVICE_TYPE_EMERGENCY}
645      * @param callType the call type. Can be one of the following:
646      *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
647      *                 {@link #CALL_TYPE_VOICE},
648      *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
649      *                 {@link #CALL_TYPE_VT},
650      *                 {@link #CALL_TYPE_VT_TX},
651      *                 {@link #CALL_TYPE_VT_RX},
652      *                 {@link #CALL_TYPE_VT_NODIR},
653      *                 {@link #CALL_TYPE_VS},
654      *                 {@link #CALL_TYPE_VS_TX},
655      *                 {@link #CALL_TYPE_VS_RX}
656      * @param callExtras A bundle with the call extras.
657      * @param mediaProfile The IMS stream media profile.
658      */
ImsCallProfile(int serviceType, int callType, Bundle callExtras, ImsStreamMediaProfile mediaProfile)659     public ImsCallProfile(int serviceType, int callType, Bundle callExtras,
660             ImsStreamMediaProfile mediaProfile) {
661         mServiceType = serviceType;
662         mCallType = callType;
663         mCallExtras = callExtras;
664         mMediaProfile = mediaProfile;
665     }
666 
getCallExtra(String name)667     public String getCallExtra(String name) {
668         return getCallExtra(name, "");
669     }
670 
getCallExtra(String name, String defaultValue)671     public String getCallExtra(String name, String defaultValue) {
672         if (mCallExtras == null) {
673             return defaultValue;
674         }
675 
676         return mCallExtras.getString(name, defaultValue);
677     }
678 
getCallExtraBoolean(String name)679     public boolean getCallExtraBoolean(String name) {
680         return getCallExtraBoolean(name, false);
681     }
682 
getCallExtraBoolean(String name, boolean defaultValue)683     public boolean getCallExtraBoolean(String name, boolean defaultValue) {
684         if (mCallExtras == null) {
685             return defaultValue;
686         }
687 
688         return mCallExtras.getBoolean(name, defaultValue);
689     }
690 
getCallExtraInt(String name)691     public int getCallExtraInt(String name) {
692         return getCallExtraInt(name, -1);
693     }
694 
getCallExtraInt(String name, int defaultValue)695     public int getCallExtraInt(String name, int defaultValue) {
696         if (mCallExtras == null) {
697             return defaultValue;
698         }
699 
700         return mCallExtras.getInt(name, defaultValue);
701     }
702 
703     /**
704      * Get the call extras (Parcelable), given the extra name.
705      * @param name call extra name
706      * @return the corresponding call extra Parcelable or null if not applicable
707      */
708     @Nullable
getCallExtraParcelable(@ullable String name)709     public <T extends Parcelable> T getCallExtraParcelable(@Nullable String name) {
710         if (mCallExtras != null) {
711             return mCallExtras.getParcelable(name);
712         }
713         return null;
714     }
715 
setCallExtra(String name, String value)716     public void setCallExtra(String name, String value) {
717         if (mCallExtras != null) {
718             mCallExtras.putString(name, value);
719         }
720     }
721 
setCallExtraBoolean(String name, boolean value)722     public void setCallExtraBoolean(String name, boolean value) {
723         if (mCallExtras != null) {
724             mCallExtras.putBoolean(name, value);
725         }
726     }
727 
setCallExtraInt(String name, int value)728     public void setCallExtraInt(String name, int value) {
729         if (mCallExtras != null) {
730             mCallExtras.putInt(name, value);
731         }
732     }
733 
734     /**
735      * Set the call extra value (Parcelable), given the call extra name.
736      *
737      * Note that the {@link Parcelable} provided must be a class defined in the Android API surface,
738      * as opposed to a class defined by your app.
739      *
740      * @param name call extra name
741      * @param parcelable call extra value
742      */
setCallExtraParcelable(@onNull String name, @NonNull Parcelable parcelable)743     public void setCallExtraParcelable(@NonNull String name, @NonNull Parcelable parcelable) {
744         if (mCallExtras != null) {
745             mCallExtras.putParcelable(name, parcelable);
746         }
747     }
748 
749     /**
750      * Set the call restrict cause, which provides the reason why a call has been restricted from
751      * using High Definition media.
752      */
setCallRestrictCause(@allRestrictCause int cause)753     public void setCallRestrictCause(@CallRestrictCause int cause) {
754         mRestrictCause = cause;
755     }
756 
updateCallType(ImsCallProfile profile)757     public void updateCallType(ImsCallProfile profile) {
758         mCallType = profile.mCallType;
759     }
760 
updateCallExtras(ImsCallProfile profile)761     public void updateCallExtras(ImsCallProfile profile) {
762         mCallExtras.clear();
763         mCallExtras = (Bundle) profile.mCallExtras.clone();
764     }
765 
766     /**
767      * Updates the media profile for the call.
768      *
769      * @param profile Call profile with new media profile.
770      */
updateMediaProfile(ImsCallProfile profile)771     public void updateMediaProfile(ImsCallProfile profile) {
772         mMediaProfile = profile.mMediaProfile;
773     }
774 
775     /**
776      * Sets the verification status for the phone number of an incoming call as identified in
777      * ATIS-1000082.
778      * <p>
779      * The ImsService should parse the verstat information from the SIP INVITE headers for the call
780      * to determine this information.  It is typically found in the P-Asserted-Identity OR From
781      * header fields.
782      * @param callerNumberVerificationStatus the new verification status.
783      */
setCallerNumberVerificationStatus( @erificationStatus int callerNumberVerificationStatus)784     public void setCallerNumberVerificationStatus(
785             @VerificationStatus int callerNumberVerificationStatus) {
786         mCallerNumberVerificationStatus = callerNumberVerificationStatus;
787     }
788 
789     /**
790      * Gets the verification status for the phone number of an incoming call as identified in
791      * ATIS-1000082.
792      * @return the verification status.
793      */
getCallerNumberVerificationStatus()794     public @VerificationStatus int getCallerNumberVerificationStatus() {
795         return mCallerNumberVerificationStatus;
796     }
797 
798     @NonNull
799     @Override
toString()800     public String toString() {
801         return "{ serviceType=" + mServiceType
802                 + ", callType=" + mCallType
803                 + ", restrictCause=" + mRestrictCause
804                 + ", mediaProfile=" + (mMediaProfile != null ? mMediaProfile.toString() : "null")
805                 + ", emergencyServiceCategories=" + mEmergencyServiceCategories
806                 + ", emergencyUrns=" + mEmergencyUrns
807                 + ", emergencyCallRouting=" + mEmergencyCallRouting
808                 + ", emergencyCallTesting=" + mEmergencyCallTesting
809                 + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency
810                 + ", mRestrictCause=" + mRestrictCause
811                 + ", mCallerNumberVerstat= " + mCallerNumberVerificationStatus
812                 + ", mAcceptedRtpHeaderExtensions= " + mAcceptedRtpHeaderExtensionTypes
813                 + " }";
814     }
815 
816     @Override
describeContents()817     public int describeContents() {
818         return 0;
819     }
820 
821     @Override
writeToParcel(Parcel out, int flags)822     public void writeToParcel(Parcel out, int flags) {
823         Bundle filteredExtras = maybeCleanseExtras(mCallExtras);
824         out.writeInt(mServiceType);
825         out.writeInt(mCallType);
826         out.writeBundle(filteredExtras);
827         out.writeParcelable(mMediaProfile, 0);
828         out.writeInt(mEmergencyServiceCategories);
829         out.writeStringList(mEmergencyUrns);
830         out.writeInt(mEmergencyCallRouting);
831         out.writeBoolean(mEmergencyCallTesting);
832         out.writeBoolean(mHasKnownUserIntentEmergency);
833         out.writeInt(mRestrictCause);
834         out.writeInt(mCallerNumberVerificationStatus);
835         out.writeArray(mAcceptedRtpHeaderExtensionTypes.toArray());
836     }
837 
readFromParcel(Parcel in)838     private void readFromParcel(Parcel in) {
839         mServiceType = in.readInt();
840         mCallType = in.readInt();
841         mCallExtras = in.readBundle();
842         mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader());
843         mEmergencyServiceCategories = in.readInt();
844         mEmergencyUrns = in.createStringArrayList();
845         mEmergencyCallRouting = in.readInt();
846         mEmergencyCallTesting = in.readBoolean();
847         mHasKnownUserIntentEmergency = in.readBoolean();
848         mRestrictCause = in.readInt();
849         mCallerNumberVerificationStatus = in.readInt();
850         Object[] accepted = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
851         mAcceptedRtpHeaderExtensionTypes = Arrays.stream(accepted)
852                 .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
853     }
854 
855     public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR =
856             new Creator<ImsCallProfile>() {
857         @Override
858         public ImsCallProfile createFromParcel(Parcel in) {
859             return new ImsCallProfile(in);
860         }
861 
862         @Override
863         public ImsCallProfile[] newArray(int size) {
864             return new ImsCallProfile[size];
865         }
866     };
867 
getServiceType()868     public int getServiceType() {
869         return mServiceType;
870     }
871 
getCallType()872     public int getCallType() {
873         return mCallType;
874     }
875 
876     /**
877      * @return The call restrict cause, which provides the reason why a call has been restricted
878      * from using High Definition media.
879      */
getRestrictCause()880     public @CallRestrictCause int getRestrictCause() {
881         return mRestrictCause;
882     }
883 
getCallExtras()884     public Bundle getCallExtras() {
885         return mCallExtras;
886     }
887 
888     /**
889      * Get the proprietary extras set for this ImsCallProfile.
890      * @return A {@link Bundle} containing proprietary call extras that were not set by the
891      * platform.
892      */
getProprietaryCallExtras()893     public @NonNull Bundle getProprietaryCallExtras() {
894         if (mCallExtras == null) {
895             return new Bundle();
896         }
897         Bundle proprietaryExtras = mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
898         if (proprietaryExtras == null) {
899             return new Bundle();
900         }
901         // Make a copy so users do not accidentally change this copy of the extras.
902         return new Bundle(proprietaryExtras);
903     }
904 
getMediaProfile()905     public ImsStreamMediaProfile getMediaProfile() {
906         return mMediaProfile;
907     }
908 
909     /**
910      * Converts from the call types defined in {@link ImsCallProfile} to the
911      * video state values defined in {@link VideoProfile}.
912      *
913      * @param callProfile The call profile.
914      * @return The video state.
915      */
getVideoStateFromImsCallProfile(ImsCallProfile callProfile)916     public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) {
917         int videostate = getVideoStateFromCallType(callProfile.mCallType);
918         if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) {
919             videostate |= VideoProfile.STATE_PAUSED;
920         } else {
921             videostate &= ~VideoProfile.STATE_PAUSED;
922         }
923         return videostate;
924     }
925 
926     /**
927      * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state.
928      * @param callType The call type.
929      * @return The video state.
930      */
getVideoStateFromCallType(int callType)931     public static int getVideoStateFromCallType(int callType) {
932         int videostate = VideoProfile.STATE_AUDIO_ONLY;
933         switch (callType) {
934             case CALL_TYPE_VT_TX:
935                 videostate = VideoProfile.STATE_TX_ENABLED;
936                 break;
937             case CALL_TYPE_VT_RX:
938                 videostate = VideoProfile.STATE_RX_ENABLED;
939                 break;
940             case CALL_TYPE_VT:
941                 videostate = VideoProfile.STATE_BIDIRECTIONAL;
942                 break;
943             case CALL_TYPE_VOICE:
944                 videostate = VideoProfile.STATE_AUDIO_ONLY;
945                 break;
946             default:
947                 videostate = VideoProfile.STATE_AUDIO_ONLY;
948                 break;
949         }
950         return videostate;
951     }
952 
953     /**
954      * Converts from the video state values defined in {@link VideoProfile}
955      * to the call types defined in {@link ImsCallProfile}.
956      *
957      * @param videoState The video state.
958      * @return The call type.
959      */
getCallTypeFromVideoState(int videoState)960     public static int getCallTypeFromVideoState(int videoState) {
961         boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED);
962         boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED);
963         boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED);
964         if (isPaused) {
965             return ImsCallProfile.CALL_TYPE_VT_NODIR;
966         } else if (videoTx && !videoRx) {
967             return ImsCallProfile.CALL_TYPE_VT_TX;
968         } else if (!videoTx && videoRx) {
969             return ImsCallProfile.CALL_TYPE_VT_RX;
970         } else if (videoTx && videoRx) {
971             return ImsCallProfile.CALL_TYPE_VT;
972         }
973         return ImsCallProfile.CALL_TYPE_VOICE;
974     }
975 
976     /**
977      * Badly named old method, kept for compatibility.
978      * See {@link #presentationToOir(int)}.
979      * @hide
980      */
981     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
presentationToOIR(int presentation)982     public static int presentationToOIR(int presentation) {
983         switch (presentation) {
984             case PhoneConstants.PRESENTATION_RESTRICTED:
985                 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
986             case PhoneConstants.PRESENTATION_ALLOWED:
987                 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
988             case PhoneConstants.PRESENTATION_PAYPHONE:
989                 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
990             case PhoneConstants.PRESENTATION_UNKNOWN:
991                 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
992             default:
993                 return ImsCallProfile.OIR_DEFAULT;
994         }
995     }
996 
997     /**
998      * Translate presentation value to OIR value
999      * @param presentation
1000      * @return OIR values
1001      */
presentationToOir(int presentation)1002     public static int presentationToOir(int presentation) {
1003         return presentationToOIR(presentation);
1004     }
1005 
1006     /**
1007      * Translate OIR value to presentation value
1008      * @param oir value
1009      * @return presentation value
1010      * @hide
1011      */
OIRToPresentation(int oir)1012     public static int OIRToPresentation(int oir) {
1013         switch(oir) {
1014             case ImsCallProfile.OIR_PRESENTATION_RESTRICTED:
1015                 return PhoneConstants.PRESENTATION_RESTRICTED;
1016             case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
1017                 return PhoneConstants.PRESENTATION_ALLOWED;
1018             case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
1019                 return PhoneConstants.PRESENTATION_PAYPHONE;
1020             case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
1021                 return PhoneConstants.PRESENTATION_UNKNOWN;
1022             default:
1023                 return PhoneConstants.PRESENTATION_UNKNOWN;
1024         }
1025     }
1026 
1027     /**
1028      * Checks if video call is paused
1029      * @return true if call is video paused
1030      */
isVideoPaused()1031     public boolean isVideoPaused() {
1032         return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE;
1033     }
1034 
1035     /**
1036      * Determines if the {@link ImsCallProfile} represents a video call.
1037      *
1038      * @return {@code true} if the profile is for a video call, {@code false} otherwise.
1039      */
isVideoCall()1040     public boolean isVideoCall() {
1041         return VideoProfile.isVideo(getVideoStateFromCallType(mCallType));
1042     }
1043 
1044     /**
1045      * Cleanses a {@link Bundle} to ensure that it contains only data of type:
1046      * 1. Primitive data types (e.g. int, bool, and other values determined by
1047      * {@link android.os.PersistableBundle#isValidType(Object)}).
1048      * 2. Other Bundles.
1049      * 3. {@link Parcelable} objects in the {@code android.*} namespace.
1050      * @param extras the source {@link Bundle}
1051      * @return where all elements are valid types the source {@link Bundle} is returned unmodified,
1052      *      otherwise a copy of the {@link Bundle} with the invalid elements is returned.
1053      */
maybeCleanseExtras(Bundle extras)1054     private Bundle maybeCleanseExtras(Bundle extras) {
1055         if (extras == null) {
1056             return null;
1057         }
1058 
1059         int startSize = extras.size();
1060         Bundle filtered = TelephonyUtils.filterValues(extras);
1061         int endSize = filtered.size();
1062         if (startSize != endSize) {
1063             Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were "
1064                     + "removed - only primitive types and system parcelables are permitted.");
1065         }
1066         return filtered;
1067     }
1068 
1069     /**
1070      * Determines if a video state is set in a video state bit-mask.
1071      *
1072      * @param videoState The video state bit mask.
1073      * @param videoStateToCheck The particular video state to check.
1074      * @return True if the video state is set in the bit-mask.
1075      */
isVideoStateSet(int videoState, int videoStateToCheck)1076     private static boolean isVideoStateSet(int videoState, int videoStateToCheck) {
1077         return (videoState & videoStateToCheck) == videoStateToCheck;
1078     }
1079 
1080     /**
1081      * Set the emergency number information. The set value is valid
1082      * only if {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
1083      *
1084      * Reference: 3gpp 23.167, Section 6 - Functional description;
1085      *            3gpp 24.503, Section 5.1.6.8.1 - General;
1086      *            3gpp 22.101, Section 10 - Emergency Calls.
1087      *
1088      * @hide
1089      */
setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency)1090     public void setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency) {
1091         setEmergencyServiceCategories(num.getEmergencyServiceCategoryBitmaskInternalDial());
1092         setEmergencyUrns(num.getEmergencyUrns());
1093         setEmergencyCallRouting(num.getEmergencyCallRouting());
1094         setEmergencyCallTesting(num.getEmergencyNumberSourceBitmask()
1095                 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
1096         setHasKnownUserIntentEmergency(hasKnownUserIntentEmergency);
1097     }
1098 
1099     /**
1100      * Set the emergency service categories. The set value is valid only if
1101      * {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
1102      *
1103      * If valid, the value is the bitwise-OR combination of the following constants:
1104      * <ol>
1105      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
1106      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
1107      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
1108      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
1109      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
1110      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
1111      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
1112      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
1113      * </ol>
1114      *
1115      * Reference: 3gpp 23.167, Section 6 - Functional description;
1116      *            3gpp 22.101, Section 10 - Emergency Calls.
1117      */
1118     @VisibleForTesting
setEmergencyServiceCategories( @mergencyServiceCategories int emergencyServiceCategories)1119     public void setEmergencyServiceCategories(
1120             @EmergencyServiceCategories int emergencyServiceCategories) {
1121         mEmergencyServiceCategories = emergencyServiceCategories;
1122     }
1123 
1124     /**
1125      * Set the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType}
1126      * returns {@link #SERVICE_TYPE_EMERGENCY}.
1127      *
1128      * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
1129      *            3gpp 22.101, Section 10 - Emergency Calls.
1130      */
1131     @VisibleForTesting
setEmergencyUrns(@onNull List<String> emergencyUrns)1132     public void setEmergencyUrns(@NonNull List<String> emergencyUrns) {
1133         mEmergencyUrns = emergencyUrns;
1134     }
1135 
1136     /**
1137      * Set the emergency call routing, only valid if {@link #getServiceType} returns
1138      * {@link #SERVICE_TYPE_EMERGENCY}
1139      *
1140      * If valid, the value is any of the following constants:
1141      * <ol>
1142      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
1143      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
1144      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
1145      * </ol>
1146      */
1147     @VisibleForTesting
setEmergencyCallRouting(@mergencyCallRouting int emergencyCallRouting)1148     public void setEmergencyCallRouting(@EmergencyCallRouting int emergencyCallRouting) {
1149         mEmergencyCallRouting = emergencyCallRouting;
1150     }
1151 
1152     /**
1153      * Set if this is for testing emergency call, only valid if {@link #getServiceType} returns
1154      * {@link #SERVICE_TYPE_EMERGENCY}.
1155      */
1156     @VisibleForTesting
setEmergencyCallTesting(boolean isTesting)1157     public void setEmergencyCallTesting(boolean isTesting) {
1158         mEmergencyCallTesting = isTesting;
1159     }
1160 
1161     /**
1162      * Set if we have known the user intent of the call is emergency.
1163      *
1164      * This is only used to specify when the dialed number is ambiguous when it can be identified
1165      * as both emergency number and any other non-emergency number; e.g. in some situation, 611
1166      * could be both an emergency number in a country and a non-emergency number of a carrier's
1167      * customer service hotline.
1168      */
1169     @VisibleForTesting
setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency)1170     public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) {
1171         mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency;
1172     }
1173 
1174     /**
1175      * Get the emergency service categories, only valid if {@link #getServiceType} returns
1176      * {@link #SERVICE_TYPE_EMERGENCY}
1177      *
1178      * @return the emergency service categories,
1179      *
1180      * If valid, the value is the bitwise-OR combination of the following constants:
1181      * <ol>
1182      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
1183      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
1184      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
1185      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
1186      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
1187      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
1188      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
1189      * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
1190      * </ol>
1191      *
1192      * Reference: 3gpp 23.167, Section 6 - Functional description;
1193      *            3gpp 22.101, Section 10 - Emergency Calls.
1194      */
getEmergencyServiceCategories()1195     public @EmergencyServiceCategories int getEmergencyServiceCategories() {
1196         return mEmergencyServiceCategories;
1197     }
1198 
1199     /**
1200      * Get the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType}
1201      * returns {@link #SERVICE_TYPE_EMERGENCY}.
1202      *
1203      * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
1204      *            3gpp 22.101, Section 10 - Emergency Calls.
1205      */
getEmergencyUrns()1206     public @NonNull List<String> getEmergencyUrns() {
1207         return mEmergencyUrns;
1208     }
1209 
1210     /**
1211      * Get the emergency call routing, only valid if {@link #getServiceType} returns
1212      * {@link #SERVICE_TYPE_EMERGENCY}
1213      *
1214      * If valid, the value is any of the following constants:
1215      * <ol>
1216      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
1217      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
1218      * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
1219      * </ol>
1220      */
getEmergencyCallRouting()1221     public @EmergencyCallRouting int getEmergencyCallRouting() {
1222         return mEmergencyCallRouting;
1223     }
1224 
1225     /**
1226      * Get if the emergency call is for testing purpose.
1227      */
isEmergencyCallTesting()1228     public boolean isEmergencyCallTesting() {
1229         return mEmergencyCallTesting;
1230     }
1231 
1232     /**
1233      * Checks if we have known the user intent of the call is emergency.
1234      *
1235      * This is only used to specify when the dialed number is ambiguous when it can be identified
1236      * as both emergency number and any other non-emergency number; e.g. in some situation, 611
1237      * could be both an emergency number in a country and a non-emergency number of a carrier's
1238      * customer service hotline.
1239      */
hasKnownUserIntentEmergency()1240     public boolean hasKnownUserIntentEmergency() {
1241         return mHasKnownUserIntentEmergency;
1242     }
1243 
1244     /**
1245      * Gets the {@link RtpHeaderExtensionType}s which have been accepted by both ends of the call.
1246      * <p>
1247      * According to RFC8285, RTP header extensions available to a call are determined using the
1248      * offer/accept phase of the SDP protocol (see RFC4566).
1249      * <p>
1250      * The offered header extension types supported by the framework and exposed to the
1251      * {@link ImsService} via {@link MmTelFeature#changeOfferedRtpHeaderExtensionTypes(Set)}.
1252      *
1253      * @return the {@link RtpHeaderExtensionType}s which were accepted by the other end of the call.
1254      */
getAcceptedRtpHeaderExtensionTypes()1255     public @NonNull Set<RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes() {
1256         return mAcceptedRtpHeaderExtensionTypes;
1257     }
1258 
1259     /**
1260      * Sets the accepted {@link RtpHeaderExtensionType}s for this call.
1261      * <p>
1262      * According to RFC8285, RTP header extensions available to a call are determined using the
1263      * offer/accept phase of the SDP protocol (see RFC4566).
1264      *
1265      * @param rtpHeaderExtensions
1266      */
setAcceptedRtpHeaderExtensionTypes(@onNull Set<RtpHeaderExtensionType> rtpHeaderExtensions)1267     public void setAcceptedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
1268             rtpHeaderExtensions) {
1269         mAcceptedRtpHeaderExtensionTypes.clear();
1270         mAcceptedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
1271     }
1272 }
1273