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