/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.telephony.ims;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telecom.VideoProfile;
import android.telephony.CallState;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.ims.feature.MmTelFeature;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.util.TelephonyUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
 * additional information related to the call.
 * <p>
 * See the following specifications for more information about this class: GSMA IR.92/IR.94,
 * 3GPP TS 24.229/TS 26.114/TS26.111.
 * @hide
 */
@SystemApi
public final class ImsCallProfile implements Parcelable {
    private static final String TAG = "ImsCallProfile";

    /**
     * Service types
     */
    /**
     * It is for a special case. It helps that the application can make a call
     * without IMS connection (not registered).
     * In the moment of the call initiation, the device try to connect to the IMS network
     * and initiates the call.
     */
    public static final int SERVICE_TYPE_NONE = 0;
    /**
     * It is a default type and can be selected when the device is connected to the IMS network.
     */
    public static final int SERVICE_TYPE_NORMAL = 1;
    /**
     * It is for an emergency call.
     */
    public static final int SERVICE_TYPE_EMERGENCY = 2;

    /**
     * This value is returned if there is no valid IMS call type defined for the call. For example,
     * if an ongoing call is circuit-switched and {@link CallState#getImsCallType()} is called, this
     * value will be returned.
     */
    public static final int CALL_TYPE_NONE = 0;
    /**
     * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     */
    public static final int CALL_TYPE_VOICE_N_VIDEO = 1;
    /**
     * IR.92 (Voice only)
     */
    public static final int CALL_TYPE_VOICE = 2;
    /**
     * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     */
    public static final int CALL_TYPE_VIDEO_N_VOICE = 3;
    /**
     * Video Telephony (audio / video two way)
     */
    public static final int CALL_TYPE_VT = 4;
    /**
     * Video Telephony (audio two way / video TX one way)
     */
    public static final int CALL_TYPE_VT_TX = 5;
    /**
     * Video Telephony (audio two way / video RX one way)
     */
    public static final int CALL_TYPE_VT_RX = 6;
    /**
     * Video Telephony (audio two way / video inactive)
     */
    public static final int CALL_TYPE_VT_NODIR = 7;
    /**
     * VideoShare (video two way)
     */
    public static final int CALL_TYPE_VS = 8;
    /**
     * VideoShare (video TX one way)
     */
    public static final int CALL_TYPE_VS_TX = 9;
    /**
     * VideoShare (video RX one way)
     */
    public static final int CALL_TYPE_VS_RX = 10;

    /**
     * Extra properties for IMS call.
     */
    /**
     * Boolean extra properties - "true" / "false"
     *  conference : Indicates if the session is for the conference call or not.
     *  e_call : Indicates if the session is for the emergency call or not.
     *  vms : Indicates if the session is connected to the voice mail system or not.
     *  call_mode_changeable : Indicates if the session is able to upgrade/downgrade
     *      the video during voice call.
     *  conference_avail : Indicates if the session can be extended to the conference.
     */

    /**
     * Indicates if the session is for a conference call or not. If not defined, should be
     * considered {@code false}.
     * Boolean extra properties - {@code true} / {@code false}.
     *
     * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
     * @hide
     */
    @SystemApi
    public static final String EXTRA_CONFERENCE = "android.telephony.ims.extra.CONFERENCE";

    /**
     * The previous string of EXTRA_CONFERENCE. Use EXTRA_CONFERENCE whenever possible.
     * For external app or vendor code backward compatibility, we should always set value for both
     * EXTRA_CONFERENCE_DEPRECATED and EXTRA_CONFERENCE.
     *
     * @deprecated Remove when not needed anymore.
     *
     * @hide
     */
    public static final String EXTRA_CONFERENCE_DEPRECATED = "conference";

    /**
     * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an
     * emergency call.  The {@link ImsService} sets this on a call to indicate that the network has
     * identified the call as an emergency call.
     */
    public static final String EXTRA_EMERGENCY_CALL = "e_call";

    /**
     * @hide
     */
    public static final String EXTRA_VMS = "vms";
    /**
     * @hide
     */
    public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";

    /**
     * Indicates if the session can be extended to a conference call. If not defined, should be
     * considered {@code false}.
     * Boolean extra properties - {@code true} / {@code false}.
     *
     * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
     * @hide
     */
    @SystemApi
    public static final String EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED =
            "android.telephony.ims.extra.EXTENDING_TO_CONFERENCE_SUPPORTED";

    /**
     * The previous string of EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED.
     * Use EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED whenever possible.
     * For backward compatibility, we should always set value for both
     * EXTRA_EXTENDING_TO_CONFERENCE_SUPPORTED and EXTRA_CONFERENCE_AVAIL.
     *
     * @deprecated Remove when not needed anymore.
     *
     * @hide
     */
    public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";

    /**
     * Extra key used to store a Bundle containing proprietary extras to send to the ImsService.
     * Use {@link #getProprietaryCallExtras()} instead.
     * @hide
     */
    @TestApi
    public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";

    /**
     * Rule for originating identity (number) presentation, MO/MT.
     *      {@link ImsCallProfile#OIR_DEFAULT}
     *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
     *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
     */
    public static final String EXTRA_OIR = "oir";
    /**
     * Rule for calling name presentation
     *      {@link ImsCallProfile#OIR_DEFAULT}
     *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
     *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
     */
    public static final String EXTRA_CNAP = "cnap";
    /**
     * To identify the Ims call type, MO
     *      {@link ImsCallProfile#DIALSTRING_NORMAL}
     *      {@link ImsCallProfile#DIALSTRING_SS_CONF}
     *      {@link ImsCallProfile#DIALSTRING_USSD}
     */
    public static final String EXTRA_DIALSTRING = "dialstring";
    /**
     * This extra holds call fail cause because of which redial is attempted.
     * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*}
     * for possible values this extra can hold.
     *
     * @hide
     */
    public static final String EXTRA_RETRY_CALL_FAIL_REASON =
            "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON";
    /**
     * This extra holds call network type on which lower layers
     * may try attempting redial.
     * See {@link TelephonyManager} {@code NETWORK_TYPE_*}
     * for possible values this extra can hold.
     *
     * @hide
     */
    public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE =
            "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE";

    /**
     * Extra for the call composer call priority, either {@link ImsCallProfile#PRIORITY_NORMAL} or
     * {@link ImsCallProfile#PRIORITY_URGENT}. It can be set via
     * {@link #setCallExtraInt(String, int)}.
     *
     * Reference: RCC.20 Section 2.4.4.2
     */
    public static final String EXTRA_PRIORITY = "android.telephony.ims.extra.PRIORITY";

    // TODO(hallliu) remove the reference to the maximum length and update it later.
    /**
     * Extra for the call composer call subject, a string of maximum length 60 characters.
     * It can be set via {@link #setCallExtra(String, String)}.
     *
     * Reference: RCC.20 Section 2.4.3.2
     */
    public static final String EXTRA_CALL_SUBJECT = "android.telephony.ims.extra.CALL_SUBJECT";

    /**
     * Extra for the call composer call location, an {@Link android.location.Location} parcelable
     * class to represent the geolocation as a latitude and longitude pair. It can be set via
     * {@link #setCallExtraParcelable(String, Parcelable)}.
     *
     * Reference: RCC.20 Section 2.4.3.2
     */
    public static final String EXTRA_LOCATION = "android.telephony.ims.extra.LOCATION";

    /**
     * Extra for the call composer picture URL, a String that indicates the URL on the carrier’s
     * server infrastructure to get the picture. It can be set via
     * {@link #setCallExtra(String, String)}.
     *
     * Note that this URL is not intended to be parsed by the IMS stack -- it should be sent
     * directly to the network for consumption by the called party or forwarded directly from the
     * network to the platform for caching and download.
     *
     * Reference: RCC.20 Section 2.4.3.2
     */
    public static final String EXTRA_PICTURE_URL = "android.telephony.ims.extra.PICTURE_URL";

    /**
     * Boolean extra indicating whether the call is a business call.
     *
     * This extra will be set to {@code true} if and only if the SIP INVITE headers contain the
     * "Organization" header.
     */
    public static final String EXTRA_IS_BUSINESS_CALL =
            "android.telephony.ims.extra.IS_BUSINESS_CALL";

    /**
     * Values for EXTRA_OIR / EXTRA_CNAP
     */
    /**
     * Default presentation for Originating Identity.
     */
    public static final int OIR_DEFAULT = 0;    // "user subscription default value"
    /**
     * Restricted presentation for Originating Identity.
     */
    public static final int OIR_PRESENTATION_RESTRICTED = 1;
    /**
     * Not restricted presentation for Originating Identity.
     */
    public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
    /**
     * Presentation unknown for Originating Identity.
     */
    public static final int OIR_PRESENTATION_UNKNOWN = 3;
    /**
     * Payphone presentation for Originating Identity.
     */
    public static final int OIR_PRESENTATION_PAYPHONE = 4;
    /**
     * Unavailable presentation for Originating Identity.
     */
    public static final int OIR_PRESENTATION_UNAVAILABLE = 5;

    //Values for EXTRA_DIALSTRING
    /**
     * A default or normal normal call.
     */
    public static final int DIALSTRING_NORMAL = 0;
    /**
     * Call for SIP-based user configuration
     */
    public static final int DIALSTRING_SS_CONF = 1;
    /**
     * Call for USSD message
     */
    public static final int DIALSTRING_USSD = 2;

    // Values for EXTRA_PRIORITY
    /**
     * Indicates the call composer call priority is normal.
     *
     * Reference: RCC.20 Section 2.4.4.2
     */
    public static final int PRIORITY_NORMAL = 0;

    /**
     * Indicates the call composer call priority is urgent.
     *
     * Reference: RCC.20 Section 2.4.4.2
     */
    public static final int PRIORITY_URGENT = 1;

    /**
     * Call is not restricted on peer side and High Definition media is supported
     */
    public static final int CALL_RESTRICT_CAUSE_NONE = 0;

    /**
     * High Definition media is not supported on the peer side due to the Radio Access Technology
     * (RAT) it is are connected to.
     */
    public static final int CALL_RESTRICT_CAUSE_RAT = 1;

    /**
     * The service has been disabled on the peer side.
     */
    public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;

    /**
     * High definition media is not currently supported.
     */
    public static final int CALL_RESTRICT_CAUSE_HD = 3;

    /**@hide*/
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "CALL_RESTRICT_CAUSE_", value = {
            CALL_RESTRICT_CAUSE_NONE,
            CALL_RESTRICT_CAUSE_RAT,
            CALL_RESTRICT_CAUSE_DISABLED,
            CALL_RESTRICT_CAUSE_HD
    })
    public @interface CallRestrictCause {}

    /**
     * String extra properties
     *  oi : Originating identity (number), MT only
     *  cna : Calling name
     *  ussd : For network-initiated USSD, MT only
     *  remote_uri : Connected user identity (it can be used for the conference)
     *  ChildNum: Child number info.
     *  Codec: Codec info.
     *  DisplayText: Display text for the call.
     *  AdditionalCallInfo: Additional call info.
     *  CallPull: Boolean value specifying if the call is a pulled call.
     */
    public static final String EXTRA_OI = "oi";
    public static final String EXTRA_CNA = "cna";
    public static final String EXTRA_USSD = "ussd";
    public static final String EXTRA_REMOTE_URI = "remote_uri";
    public static final String EXTRA_CHILD_NUMBER = "ChildNum";
    public static final String EXTRA_CODEC = "Codec";
    public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
    public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
    public static final String EXTRA_IS_CALL_PULL = "CallPull";

    /**
     * String extra property
     *  Containing fields from the SIP INVITE message for an IMS call
     */
    public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS =
                                  "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";

    /**
     * CallDisconnectCause: Specify call disconnect cause. This extra should be a code
     * corresponding to ImsReasonInfo and should only be populated in the case that the
     * call has already been missed
     */
    public static final String EXTRA_CALL_DISCONNECT_CAUSE =
                                 "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";

    /**
     * Extra key which the RIL can use to indicate the radio technology used for a call.
     * Valid values are:
     * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
     * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
     * {@code RIL_RADIO_TECHNOLOGY_*} constants.
     * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
     * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
     * "14" vs (int) 14).
     * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
     *      updateImsCallRatFromExtras(Bundle)} to determine whether to set the
     * {@link android.telecom.TelecomManager#EXTRA_CALL_NETWORK_TYPE} extra value and
     * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
     * @deprecated the constants associated with this extra are hidden, instead use
     * {@link #EXTRA_CALL_NETWORK_TYPE}.
     */
    @Deprecated
    public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";

    /**
     * Extra key with an {@code int} value which can be set in {@link #setCallExtraInt(String, int)}
     * to indicate the network type used for a call.
     * <p>
     * Valid values are defined by {@code TelephonyManager.NETWORK_TYPE_*} constants. An example may
     * be {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}.
     */
    public static final String EXTRA_CALL_NETWORK_TYPE =
            "android.telephony.ims.extra.CALL_NETWORK_TYPE";

    /**
     * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'.  Used to ensure
     * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE}
     * extra key.  Should be removed when the non-compliant modems are fixed.
     * @hide
     * @deprecated Use {@link #EXTRA_CALL_NETWORK_TYPE} instead.
     */
    @Deprecated
    public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech";

    /**
     * String extra property containing forwarded numbers associated with the current connection
     * for an IMS call. The value is string array, and it can include multiple numbers, and
     * the array values are expected E164 (e.g. +1 (650) 253-0000) format.
     */
    public static final String EXTRA_FORWARDED_NUMBER =
            "android.telephony.ims.extra.FORWARDED_NUMBER";

    /**
     * Extra key with an {@code boolean} value which can be set in
     * {@link #setCallExtraBoolean(String, boolean)} to indicate whether call is a cross sim call.
     * <p>
     * Valid values are true if call is cross sim call else false.
     */
    public static final String EXTRA_IS_CROSS_SIM_CALL =
            "android.telephony.ims.extra.IS_CROSS_SIM_CALL";

    /** @hide */
    public int mServiceType;
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public int mCallType;
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;

    /**
     * The VERSTAT for an incoming call's phone number.
     */
    private @VerificationStatus int mCallerNumberVerificationStatus;

    /**
     * Indicates that the network could not perform verification.
     */
    public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0;

    /**
     * Indicates that verification by the network passed.  This indicates there is a high likelihood
     * that the call originated from a valid source.
     */
    public static final int VERIFICATION_STATUS_PASSED = 1;

    /**
     * Indicates that verification by the network failed.  This indicates there is a high likelihood
     * that the call did not originate from a valid source.
     */
    public static final int VERIFICATION_STATUS_FAILED = 2;

    /**@hide*/
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "VERIFICATION_STATUS_", value = {
            VERIFICATION_STATUS_NOT_VERIFIED,
            VERIFICATION_STATUS_PASSED,
            VERIFICATION_STATUS_FAILED
    })
    public @interface VerificationStatus {}

    /**
     * The emergency service categories, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}
     *
     * If valid, the value is the bitwise-OR combination of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
     * </ol>
     *
     * Reference: 3gpp 23.167, Section 6 - Functional description;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    private @EmergencyServiceCategories int mEmergencyServiceCategories =
            EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;

    /**
     * The emergency Uniform Resource Names (URN), only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}.
     *
     * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    private List<String> mEmergencyUrns = new ArrayList<>();

    /**
     * The emergency call routing, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}
     *
     * If valid, the value is any of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
     * </ol>
     */
    private @EmergencyCallRouting int mEmergencyCallRouting =
            EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;

    /** Indicates if the call is for testing purpose */
    private boolean mEmergencyCallTesting = false;

    /** Indicates if we have known the intent of the user for the call is emergency */
    private boolean mHasKnownUserIntentEmergency = false;

    private Set<RtpHeaderExtensionType> mAcceptedRtpHeaderExtensionTypes = new ArraySet<>();

    /**
     * Extras associated with this {@link ImsCallProfile}.
     * <p>
     * Valid data types include:
     * <ul>
     *     <li>{@link Integer} (and int)</li>
     *     <li>{@link Long} (and long)</li>
     *     <li>{@link Double} (and double)</li>
     *     <li>{@link String}</li>
     *     <li>{@code int[]}</li>
     *     <li>{@code long[]}</li>
     *     <li>{@code double[]}</li>
     *     <li>{@code String[]}</li>
     *     <li>{@link android.os.PersistableBundle}</li>
     *     <li>{@link Boolean} (and boolean)</li>
     *     <li>{@code boolean[]}</li>
     *     <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
     * </ul>
     * <p>
     * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across
     * a {@link android.os.Binder}.
     */
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Bundle mCallExtras;
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public ImsStreamMediaProfile mMediaProfile;

    /** @hide */
    public ImsCallProfile(Parcel in) {
        readFromParcel(in);
    }

    /**
     * Default Constructor that initializes the call profile with service type
     * {@link #SERVICE_TYPE_NORMAL} and call type {@link #CALL_TYPE_VIDEO_N_VOICE}
     */
    public ImsCallProfile() {
        mServiceType = SERVICE_TYPE_NORMAL;
        mCallType = CALL_TYPE_VOICE_N_VIDEO;
        mCallExtras = new Bundle();
        mMediaProfile = new ImsStreamMediaProfile();
    }

    /**
     * Constructor.
     *
     * @param serviceType the service type for the call. Can be one of the following:
     *                    {@link #SERVICE_TYPE_NONE},
     *                    {@link #SERVICE_TYPE_NORMAL},
     *                    {@link #SERVICE_TYPE_EMERGENCY}
     * @param callType the call type. Can be one of the following:
     *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
     *                 {@link #CALL_TYPE_VOICE},
     *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
     *                 {@link #CALL_TYPE_VT},
     *                 {@link #CALL_TYPE_VT_TX},
     *                 {@link #CALL_TYPE_VT_RX},
     *                 {@link #CALL_TYPE_VT_NODIR},
     *                 {@link #CALL_TYPE_VS},
     *                 {@link #CALL_TYPE_VS_TX},
     *                 {@link #CALL_TYPE_VS_RX}
     */
    public ImsCallProfile(int serviceType, int callType) {
        mServiceType = serviceType;
        mCallType = callType;
        mCallExtras = new Bundle();
        mMediaProfile = new ImsStreamMediaProfile();
    }

    /**
     * Constructor.
     *
     * @param serviceType the service type for the call. Can be one of the following:
     *                    {@link #SERVICE_TYPE_NONE},
     *                    {@link #SERVICE_TYPE_NORMAL},
     *                    {@link #SERVICE_TYPE_EMERGENCY}
     * @param callType the call type. Can be one of the following:
     *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
     *                 {@link #CALL_TYPE_VOICE},
     *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
     *                 {@link #CALL_TYPE_VT},
     *                 {@link #CALL_TYPE_VT_TX},
     *                 {@link #CALL_TYPE_VT_RX},
     *                 {@link #CALL_TYPE_VT_NODIR},
     *                 {@link #CALL_TYPE_VS},
     *                 {@link #CALL_TYPE_VS_TX},
     *                 {@link #CALL_TYPE_VS_RX}
     * @param callExtras A bundle with the call extras.
     * @param mediaProfile The IMS stream media profile.
     */
    public ImsCallProfile(int serviceType, int callType, Bundle callExtras,
            ImsStreamMediaProfile mediaProfile) {
        mServiceType = serviceType;
        mCallType = callType;
        mCallExtras = callExtras;
        mMediaProfile = mediaProfile;
    }

    public String getCallExtra(String name) {
        return getCallExtra(name, "");
    }

    public String getCallExtra(String name, String defaultValue) {
        if (mCallExtras == null) {
            return defaultValue;
        }

        return mCallExtras.getString(name, defaultValue);
    }

    public boolean getCallExtraBoolean(String name) {
        return getCallExtraBoolean(name, false);
    }

    public boolean getCallExtraBoolean(String name, boolean defaultValue) {
        if (mCallExtras == null) {
            return defaultValue;
        }

        return mCallExtras.getBoolean(name, defaultValue);
    }

    public int getCallExtraInt(String name) {
        return getCallExtraInt(name, -1);
    }

    public int getCallExtraInt(String name, int defaultValue) {
        if (mCallExtras == null) {
            return defaultValue;
        }

        return mCallExtras.getInt(name, defaultValue);
    }

    /**
     * Get the call extras (Parcelable), given the extra name.
     * @param name call extra name
     * @return the corresponding call extra Parcelable or null if not applicable
     */
    @Nullable
    public <T extends Parcelable> T getCallExtraParcelable(@Nullable String name) {
        if (mCallExtras != null) {
            return mCallExtras.getParcelable(name);
        }
        return null;
    }

    public void setCallExtra(String name, String value) {
        if (mCallExtras != null) {
            mCallExtras.putString(name, value);
        }
    }

    public void setCallExtraBoolean(String name, boolean value) {
        if (mCallExtras != null) {
            mCallExtras.putBoolean(name, value);
        }
    }

    public void setCallExtraInt(String name, int value) {
        if (mCallExtras != null) {
            mCallExtras.putInt(name, value);
        }
    }

    /**
     * Set the call extra value (Parcelable), given the call extra name.
     *
     * Note that the {@link Parcelable} provided must be a class defined in the Android API surface,
     * as opposed to a class defined by your app.
     *
     * @param name call extra name
     * @param parcelable call extra value
     */
    public void setCallExtraParcelable(@NonNull String name, @NonNull Parcelable parcelable) {
        if (mCallExtras != null) {
            mCallExtras.putParcelable(name, parcelable);
        }
    }

    /**
     * Set the call restrict cause, which provides the reason why a call has been restricted from
     * using High Definition media.
     */
    public void setCallRestrictCause(@CallRestrictCause int cause) {
        mRestrictCause = cause;
    }

    public void updateCallType(ImsCallProfile profile) {
        mCallType = profile.mCallType;
    }

    public void updateCallExtras(ImsCallProfile profile) {
        mCallExtras.clear();
        mCallExtras = (Bundle) profile.mCallExtras.clone();
    }

    /**
     * Updates the media profile for the call.
     *
     * @param profile Call profile with new media profile.
     */
    public void updateMediaProfile(ImsCallProfile profile) {
        mMediaProfile = profile.mMediaProfile;
    }

    /**
     * Sets the verification status for the phone number of an incoming call as identified in
     * ATIS-1000082.
     * <p>
     * The ImsService should parse the verstat information from the SIP INVITE headers for the call
     * to determine this information.  It is typically found in the P-Asserted-Identity OR From
     * header fields.
     * @param callerNumberVerificationStatus the new verification status.
     */
    public void setCallerNumberVerificationStatus(
            @VerificationStatus int callerNumberVerificationStatus) {
        mCallerNumberVerificationStatus = callerNumberVerificationStatus;
    }

    /**
     * Gets the verification status for the phone number of an incoming call as identified in
     * ATIS-1000082.
     * @return the verification status.
     */
    public @VerificationStatus int getCallerNumberVerificationStatus() {
        return mCallerNumberVerificationStatus;
    }

    @NonNull
    @Override
    public String toString() {
        return "{ serviceType=" + mServiceType
                + ", callType=" + mCallType
                + ", restrictCause=" + mRestrictCause
                + ", mediaProfile=" + (mMediaProfile != null ? mMediaProfile.toString() : "null")
                + ", emergencyServiceCategories=" + mEmergencyServiceCategories
                + ", emergencyUrns=" + mEmergencyUrns
                + ", emergencyCallRouting=" + mEmergencyCallRouting
                + ", emergencyCallTesting=" + mEmergencyCallTesting
                + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency
                + ", mRestrictCause=" + mRestrictCause
                + ", mCallerNumberVerstat= " + mCallerNumberVerificationStatus
                + ", mAcceptedRtpHeaderExtensions= " + mAcceptedRtpHeaderExtensionTypes
                + " }";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        Bundle filteredExtras = maybeCleanseExtras(mCallExtras);
        out.writeInt(mServiceType);
        out.writeInt(mCallType);
        out.writeBundle(filteredExtras);
        out.writeParcelable(mMediaProfile, 0);
        out.writeInt(mEmergencyServiceCategories);
        out.writeStringList(mEmergencyUrns);
        out.writeInt(mEmergencyCallRouting);
        out.writeBoolean(mEmergencyCallTesting);
        out.writeBoolean(mHasKnownUserIntentEmergency);
        out.writeInt(mRestrictCause);
        out.writeInt(mCallerNumberVerificationStatus);
        out.writeArray(mAcceptedRtpHeaderExtensionTypes.toArray());
    }

    private void readFromParcel(Parcel in) {
        mServiceType = in.readInt();
        mCallType = in.readInt();
        mCallExtras = in.readBundle();
        mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader(), android.telephony.ims.ImsStreamMediaProfile.class);
        mEmergencyServiceCategories = in.readInt();
        mEmergencyUrns = in.createStringArrayList();
        mEmergencyCallRouting = in.readInt();
        mEmergencyCallTesting = in.readBoolean();
        mHasKnownUserIntentEmergency = in.readBoolean();
        mRestrictCause = in.readInt();
        mCallerNumberVerificationStatus = in.readInt();
        Object[] accepted = in.readArray(RtpHeaderExtensionType.class.getClassLoader(),
                RtpHeaderExtensionType.class);
        mAcceptedRtpHeaderExtensionTypes = Arrays.stream(accepted)
                .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
    }

    public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR =
            new Creator<ImsCallProfile>() {
        @Override
        public ImsCallProfile createFromParcel(Parcel in) {
            return new ImsCallProfile(in);
        }

        @Override
        public ImsCallProfile[] newArray(int size) {
            return new ImsCallProfile[size];
        }
    };

    public int getServiceType() {
        return mServiceType;
    }

    public int getCallType() {
        return mCallType;
    }

    /**
     * @return The call restrict cause, which provides the reason why a call has been restricted
     * from using High Definition media.
     */
    public @CallRestrictCause int getRestrictCause() {
        return mRestrictCause;
    }

    public Bundle getCallExtras() {
        return mCallExtras;
    }

    /**
     * Get the proprietary extras set for this ImsCallProfile.
     * @return A {@link Bundle} containing proprietary call extras that were not set by the
     * platform.
     */
    public @NonNull Bundle getProprietaryCallExtras() {
        if (mCallExtras == null) {
            return new Bundle();
        }
        Bundle proprietaryExtras = mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
        if (proprietaryExtras == null) {
            return new Bundle();
        }
        // Make a copy so users do not accidentally change this copy of the extras.
        return new Bundle(proprietaryExtras);
    }

    public ImsStreamMediaProfile getMediaProfile() {
        return mMediaProfile;
    }

    /**
     * Converts from the call types defined in {@link ImsCallProfile} to the
     * video state values defined in {@link VideoProfile}.
     *
     * @param callProfile The call profile.
     * @return The video state.
     */
    public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) {
        int videostate = getVideoStateFromCallType(callProfile.mCallType);
        if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) {
            videostate |= VideoProfile.STATE_PAUSED;
        } else {
            videostate &= ~VideoProfile.STATE_PAUSED;
        }
        return videostate;
    }

    /**
     * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state.
     * @param callType The call type.
     * @return The video state.
     */
    public static int getVideoStateFromCallType(int callType) {
        int videostate = VideoProfile.STATE_AUDIO_ONLY;
        switch (callType) {
            case CALL_TYPE_VT_TX:
                videostate = VideoProfile.STATE_TX_ENABLED;
                break;
            case CALL_TYPE_VT_RX:
                videostate = VideoProfile.STATE_RX_ENABLED;
                break;
            case CALL_TYPE_VT:
                videostate = VideoProfile.STATE_BIDIRECTIONAL;
                break;
            case CALL_TYPE_VOICE:
                videostate = VideoProfile.STATE_AUDIO_ONLY;
                break;
            default:
                videostate = VideoProfile.STATE_AUDIO_ONLY;
                break;
        }
        return videostate;
    }

    /**
     * Converts from the video state values defined in {@link VideoProfile}
     * to the call types defined in {@link ImsCallProfile}.
     *
     * @param videoState The video state.
     * @return The call type.
     */
    public static int getCallTypeFromVideoState(int videoState) {
        boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED);
        boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED);
        boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED);
        if (isPaused) {
            return ImsCallProfile.CALL_TYPE_VT_NODIR;
        } else if (videoTx && !videoRx) {
            return ImsCallProfile.CALL_TYPE_VT_TX;
        } else if (!videoTx && videoRx) {
            return ImsCallProfile.CALL_TYPE_VT_RX;
        } else if (videoTx && videoRx) {
            return ImsCallProfile.CALL_TYPE_VT;
        }
        return ImsCallProfile.CALL_TYPE_VOICE;
    }

    /**
     * Badly named old method, kept for compatibility.
     * See {@link #presentationToOir(int)}.
     * @hide
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static int presentationToOIR(int presentation) {
        switch (presentation) {
            case PhoneConstants.PRESENTATION_RESTRICTED:
                return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
            case PhoneConstants.PRESENTATION_ALLOWED:
                return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
            case PhoneConstants.PRESENTATION_PAYPHONE:
                return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
            case PhoneConstants.PRESENTATION_UNKNOWN:
                return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
            case PhoneConstants.PRESENTATION_UNAVAILABLE:
                return ImsCallProfile.OIR_PRESENTATION_UNAVAILABLE;
            default:
                return ImsCallProfile.OIR_DEFAULT;
        }
    }

    /**
     * Translate presentation value to OIR value
     * @param presentation
     * @return OIR values
     */
    public static int presentationToOir(int presentation) {
        return presentationToOIR(presentation);
    }

    /**
     * Translate OIR value to presentation value
     * @param oir value
     * @return presentation value
     * @hide
     */
    public static int OIRToPresentation(int oir) {
        switch(oir) {
            case ImsCallProfile.OIR_PRESENTATION_RESTRICTED:
                return PhoneConstants.PRESENTATION_RESTRICTED;
            case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
                return PhoneConstants.PRESENTATION_ALLOWED;
            case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
                return PhoneConstants.PRESENTATION_PAYPHONE;
            case ImsCallProfile.OIR_PRESENTATION_UNAVAILABLE:
                return PhoneConstants.PRESENTATION_UNAVAILABLE;
            case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
                return PhoneConstants.PRESENTATION_UNKNOWN;
            default:
                return PhoneConstants.PRESENTATION_UNKNOWN;
        }
    }

    /**
     * Checks if video call is paused
     * @return true if call is video paused
     */
    public boolean isVideoPaused() {
        return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE;
    }

    /**
     * Determines if the {@link ImsCallProfile} represents a video call.
     *
     * @return {@code true} if the profile is for a video call, {@code false} otherwise.
     */
    public boolean isVideoCall() {
        return VideoProfile.isVideo(getVideoStateFromCallType(mCallType));
    }

    /**
     * Cleanses a {@link Bundle} to ensure that it contains only data of type:
     * 1. Primitive data types (e.g. int, bool, and other values determined by
     * {@link android.os.PersistableBundle#isValidType(Object)}).
     * 2. Other Bundles.
     * 3. {@link Parcelable} objects in the {@code android.*} namespace.
     * @param extras the source {@link Bundle}
     * @return where all elements are valid types the source {@link Bundle} is returned unmodified,
     *      otherwise a copy of the {@link Bundle} with the invalid elements is returned.
     */
    private Bundle maybeCleanseExtras(Bundle extras) {
        if (extras == null) {
            return null;
        }

        int startSize = extras.size();
        Bundle filtered = TelephonyUtils.filterValues(extras);
        int endSize = filtered.size();
        if (startSize != endSize) {
            Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were "
                    + "removed - only primitive types and system parcelables are permitted.");
        }
        return filtered;
    }

    /**
     * Determines if a video state is set in a video state bit-mask.
     *
     * @param videoState The video state bit mask.
     * @param videoStateToCheck The particular video state to check.
     * @return True if the video state is set in the bit-mask.
     */
    private static boolean isVideoStateSet(int videoState, int videoStateToCheck) {
        return (videoState & videoStateToCheck) == videoStateToCheck;
    }

    /**
     * Set the emergency number information. The set value is valid
     * only if {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
     *
     * Reference: 3gpp 23.167, Section 6 - Functional description;
     *            3gpp 24.503, Section 5.1.6.8.1 - General;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     *
     * @hide
     */
    public void setEmergencyCallInfo(EmergencyNumber num, boolean hasKnownUserIntentEmergency) {
        setEmergencyServiceCategories(num.getEmergencyServiceCategoryBitmaskInternalDial());
        setEmergencyUrns(num.getEmergencyUrns());
        setEmergencyCallRouting(num.getEmergencyCallRouting());
        setEmergencyCallTesting(num.getEmergencyNumberSourceBitmask()
                == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
        setHasKnownUserIntentEmergency(hasKnownUserIntentEmergency);
    }

    /**
     * Set the emergency service categories. The set value is valid only if
     * {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
     *
     * If valid, the value is the bitwise-OR combination of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
     * </ol>
     *
     * Reference: 3gpp 23.167, Section 6 - Functional description;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    @VisibleForTesting
    public void setEmergencyServiceCategories(
            @EmergencyServiceCategories int emergencyServiceCategories) {
        mEmergencyServiceCategories = emergencyServiceCategories;
    }

    /**
     * Set the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType}
     * returns {@link #SERVICE_TYPE_EMERGENCY}.
     *
     * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    @VisibleForTesting
    public void setEmergencyUrns(@NonNull List<String> emergencyUrns) {
        mEmergencyUrns = emergencyUrns;
    }

    /**
     * Set the emergency call routing, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}
     *
     * If valid, the value is any of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
     * </ol>
     */
    @VisibleForTesting
    public void setEmergencyCallRouting(@EmergencyCallRouting int emergencyCallRouting) {
        mEmergencyCallRouting = emergencyCallRouting;
    }

    /**
     * Set if this is for testing emergency call, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}.
     */
    @VisibleForTesting
    public void setEmergencyCallTesting(boolean isTesting) {
        mEmergencyCallTesting = isTesting;
    }

    /**
     * Set if we have known the user intent of the call is emergency.
     *
     * This is only used to specify when the dialed number is ambiguous when it can be identified
     * as both emergency number and any other non-emergency number; e.g. in some situation, 611
     * could be both an emergency number in a country and a non-emergency number of a carrier's
     * customer service hotline.
     */
    @VisibleForTesting
    public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) {
        mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency;
    }

    /**
     * Get the emergency service categories, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}
     *
     * @return the emergency service categories,
     *
     * If valid, the value is the bitwise-OR combination of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
     * </ol>
     *
     * Reference: 3gpp 23.167, Section 6 - Functional description;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    public @EmergencyServiceCategories int getEmergencyServiceCategories() {
        return mEmergencyServiceCategories;
    }

    /**
     * Get the emergency Uniform Resource Names (URN), only valid if {@link #getServiceType}
     * returns {@link #SERVICE_TYPE_EMERGENCY}.
     *
     * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
     *            3gpp 22.101, Section 10 - Emergency Calls.
     */
    public @NonNull List<String> getEmergencyUrns() {
        return mEmergencyUrns;
    }

    /**
     * Get the emergency call routing, only valid if {@link #getServiceType} returns
     * {@link #SERVICE_TYPE_EMERGENCY}
     *
     * If valid, the value is any of the following constants:
     * <ol>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
     * </ol>
     */
    public @EmergencyCallRouting int getEmergencyCallRouting() {
        return mEmergencyCallRouting;
    }

    /**
     * Get if the emergency call is for testing purpose.
     */
    public boolean isEmergencyCallTesting() {
        return mEmergencyCallTesting;
    }

    /**
     * Checks if we have known the user intent of the call is emergency.
     *
     * This is only used to specify when the dialed number is ambiguous when it can be identified
     * as both emergency number and any other non-emergency number; e.g. in some situation, 611
     * could be both an emergency number in a country and a non-emergency number of a carrier's
     * customer service hotline.
     */
    public boolean hasKnownUserIntentEmergency() {
        return mHasKnownUserIntentEmergency;
    }

    /**
     * Gets the {@link RtpHeaderExtensionType}s which have been accepted by both ends of the call.
     * <p>
     * According to RFC8285, RTP header extensions available to a call are determined using the
     * offer/accept phase of the SDP protocol (see RFC4566).
     * <p>
     * The offered header extension types supported by the framework and exposed to the
     * {@link ImsService} via {@link MmTelFeature#changeOfferedRtpHeaderExtensionTypes(Set)}.
     *
     * @return the {@link RtpHeaderExtensionType}s which were accepted by the other end of the call.
     */
    public @NonNull Set<RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes() {
        return mAcceptedRtpHeaderExtensionTypes;
    }

    /**
     * Sets the accepted {@link RtpHeaderExtensionType}s for this call.
     * <p>
     * According to RFC8285, RTP header extensions available to a call are determined using the
     * offer/accept phase of the SDP protocol (see RFC4566).
     *
     * @param rtpHeaderExtensions
     */
    public void setAcceptedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
            rtpHeaderExtensions) {
        mAcceptedRtpHeaderExtensionTypes.clear();
        mAcceptedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
    }
}
