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