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