Home | History | Annotate | Download | only in ims
      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.SystemApi;
     20 import android.os.Bundle;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 import android.os.PersistableBundle;
     24 import android.telecom.VideoProfile;
     25 import android.util.Log;
     26 
     27 import com.android.internal.telephony.PhoneConstants;
     28 
     29 /**
     30  * Parcelable object to handle IMS call profile.
     31  * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
     32  * It provides the service and call type, the additional information related to the call.
     33  *
     34  * @hide
     35  */
     36 @SystemApi
     37 public final class ImsCallProfile implements Parcelable {
     38     private static final String TAG = "ImsCallProfile";
     39 
     40     /**
     41      * Service types
     42      */
     43     /**
     44      * It is for a special case. It helps that the application can make a call
     45      * without IMS connection (not registered).
     46      * In the moment of the call initiation, the device try to connect to the IMS network
     47      * and initiates the call.
     48      */
     49     public static final int SERVICE_TYPE_NONE = 0;
     50     /**
     51      * It is a default type and can be selected when the device is connected to the IMS network.
     52      */
     53     public static final int SERVICE_TYPE_NORMAL = 1;
     54     /**
     55      * It is for an emergency call.
     56      */
     57     public static final int SERVICE_TYPE_EMERGENCY = 2;
     58 
     59     /**
     60      * Call types
     61      */
     62     /**
     63      * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     64      */
     65     public static final int CALL_TYPE_VOICE_N_VIDEO = 1;
     66     /**
     67      * IR.92 (Voice only)
     68      */
     69     public static final int CALL_TYPE_VOICE = 2;
     70     /**
     71      * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     72      */
     73     public static final int CALL_TYPE_VIDEO_N_VOICE = 3;
     74     /**
     75      * Video Telephony (audio / video two way)
     76      */
     77     public static final int CALL_TYPE_VT = 4;
     78     /**
     79      * Video Telephony (audio two way / video TX one way)
     80      */
     81     public static final int CALL_TYPE_VT_TX = 5;
     82     /**
     83      * Video Telephony (audio two way / video RX one way)
     84      */
     85     public static final int CALL_TYPE_VT_RX = 6;
     86     /**
     87      * Video Telephony (audio two way / video inactive)
     88      */
     89     public static final int CALL_TYPE_VT_NODIR = 7;
     90     /**
     91      * VideoShare (video two way)
     92      */
     93     public static final int CALL_TYPE_VS = 8;
     94     /**
     95      * VideoShare (video TX one way)
     96      */
     97     public static final int CALL_TYPE_VS_TX = 9;
     98     /**
     99      * VideoShare (video RX one way)
    100      */
    101     public static final int CALL_TYPE_VS_RX = 10;
    102 
    103     /**
    104      * Extra properties for IMS call.
    105      */
    106     /**
    107      * Boolean extra properties - "true" / "false"
    108      *  conference : Indicates if the session is for the conference call or not.
    109      *  e_call : Indicates if the session is for the emergency call or not.
    110      *  vms : Indicates if the session is connected to the voice mail system or not.
    111      *  call_mode_changeable : Indicates if the session is able to upgrade/downgrade
    112      *      the video during voice call.
    113      *  conference_avail : Indicates if the session can be extended to the conference.
    114      */
    115     /**
    116      * @hide
    117      */
    118     public static final String EXTRA_CONFERENCE = "conference";
    119     /**
    120      * @hide
    121      */
    122     public static final String EXTRA_E_CALL = "e_call";
    123     /**
    124      * @hide
    125      */
    126     public static final String EXTRA_VMS = "vms";
    127     /**
    128      * @hide
    129      */
    130     public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";
    131     /**
    132      * @hide
    133      */
    134     public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
    135 
    136     // Extra string for internal use only. OEMs should not use
    137     // this for packing extras.
    138     /**
    139      * @hide
    140      */
    141     public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
    142 
    143     /**
    144      * Rule for originating identity (number) presentation, MO/MT.
    145      *      {@link ImsCallProfile#OIR_DEFAULT}
    146      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
    147      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
    148      */
    149     public static final String EXTRA_OIR = "oir";
    150     /**
    151      * Rule for calling name presentation
    152      *      {@link ImsCallProfile#OIR_DEFAULT}
    153      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
    154      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
    155      */
    156     public static final String EXTRA_CNAP = "cnap";
    157     /**
    158      * To identify the Ims call type, MO
    159      *      {@link ImsCallProfile#DIALSTRING_NORMAL}
    160      *      {@link ImsCallProfile#DIALSTRING_SS_CONF}
    161      *      {@link ImsCallProfile#DIALSTRING_USSD}
    162      */
    163     public static final String EXTRA_DIALSTRING = "dialstring";
    164 
    165     /**
    166      * Values for EXTRA_OIR / EXTRA_CNAP
    167      */
    168     /**
    169      * Default presentation for Originating Identity.
    170      */
    171     public static final int OIR_DEFAULT = 0;    // "user subscription default value"
    172     /**
    173      * Restricted presentation for Originating Identity.
    174      */
    175     public static final int OIR_PRESENTATION_RESTRICTED = 1;
    176     /**
    177      * Not restricted presentation for Originating Identity.
    178      */
    179     public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
    180     /**
    181      * Presentation unknown for Originating Identity.
    182      */
    183     public static final int OIR_PRESENTATION_UNKNOWN = 3;
    184     /**
    185      * Payphone presentation for Originating Identity.
    186      */
    187     public static final int OIR_PRESENTATION_PAYPHONE = 4;
    188 
    189     //Values for EXTRA_DIALSTRING
    190     /**
    191      * A default or normal normal call.
    192      */
    193     public static final int DIALSTRING_NORMAL = 0;
    194     /**
    195      * Call for SIP-based user configuration
    196      */
    197     public static final int DIALSTRING_SS_CONF = 1;
    198     /**
    199      * Call for USSD message
    200      */
    201     public static final int DIALSTRING_USSD = 2;
    202 
    203     /**
    204      * Values for causes that restrict call types
    205      */
    206     // Default cause not restricted at peer and HD is supported
    207     public static final int CALL_RESTRICT_CAUSE_NONE = 0;
    208     // Service not supported by RAT at peer
    209     public static final int CALL_RESTRICT_CAUSE_RAT = 1;
    210     // Service Disabled at peer
    211     public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
    212     // HD is not supported
    213     public static final int CALL_RESTRICT_CAUSE_HD = 3;
    214 
    215     /**
    216      * String extra properties
    217      *  oi : Originating identity (number), MT only
    218      *  cna : Calling name
    219      *  ussd : For network-initiated USSD, MT only
    220      *  remote_uri : Connected user identity (it can be used for the conference)
    221      *  ChildNum: Child number info.
    222      *  Codec: Codec info.
    223      *  DisplayText: Display text for the call.
    224      *  AdditionalCallInfo: Additional call info.
    225      *  CallPull: Boolean value specifying if the call is a pulled call.
    226      */
    227     public static final String EXTRA_OI = "oi";
    228     public static final String EXTRA_CNA = "cna";
    229     public static final String EXTRA_USSD = "ussd";
    230     public static final String EXTRA_REMOTE_URI = "remote_uri";
    231     public static final String EXTRA_CHILD_NUMBER = "ChildNum";
    232     public static final String EXTRA_CODEC = "Codec";
    233     public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
    234     public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
    235     public static final String EXTRA_IS_CALL_PULL = "CallPull";
    236 
    237     /**
    238      * Extra key which the RIL can use to indicate the radio technology used for a call.
    239      * Valid values are:
    240      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
    241      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
    242      * {@code RIL_RADIO_TECHNOLOGY_*} constants.
    243      * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
    244      * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
    245      * "14" vs (int) 14).
    246      * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
    247      *      updateWifiStateFromExtras(Bundle)} to determine whether to set the
    248      * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
    249      */
    250     public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
    251 
    252     /**
    253      * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'.  Used to ensure
    254      * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE}
    255      * extra key.  Should be removed when the non-compliant modems are fixed.
    256      * @hide
    257      */
    258     public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech";
    259 
    260     /** @hide */
    261     public int mServiceType;
    262     /** @hide */
    263     public int mCallType;
    264     /** @hide */
    265     public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
    266 
    267     /**
    268      * Extras associated with this {@link ImsCallProfile}.
    269      * <p>
    270      * Valid data types include:
    271      * <ul>
    272      *     <li>{@link Integer} (and int)</li>
    273      *     <li>{@link Long} (and long)</li>
    274      *     <li>{@link Double} (and double)</li>
    275      *     <li>{@link String}</li>
    276      *     <li>{@code int[]}</li>
    277      *     <li>{@code long[]}</li>
    278      *     <li>{@code double[]}</li>
    279      *     <li>{@code String[]}</li>
    280      *     <li>{@link PersistableBundle}</li>
    281      *     <li>{@link Boolean} (and boolean)</li>
    282      *     <li>{@code boolean[]}</li>
    283      *     <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
    284      * </ul>
    285      * <p>
    286      * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across
    287      * a {@link android.os.Binder}.
    288      */
    289     /** @hide */
    290     public Bundle mCallExtras;
    291     /** @hide */
    292     public ImsStreamMediaProfile mMediaProfile;
    293 
    294     /** @hide */
    295     public ImsCallProfile(Parcel in) {
    296         readFromParcel(in);
    297     }
    298 
    299     /**
    300      * Default Constructor that initializes the call profile with service type
    301      * {@link #SERVICE_TYPE_NORMAL} and call type {@link #CALL_TYPE_VIDEO_N_VOICE}
    302      */
    303     public ImsCallProfile() {
    304         mServiceType = SERVICE_TYPE_NORMAL;
    305         mCallType = CALL_TYPE_VOICE_N_VIDEO;
    306         mCallExtras = new Bundle();
    307         mMediaProfile = new ImsStreamMediaProfile();
    308     }
    309 
    310     /**
    311      * Constructor.
    312      *
    313      * @param serviceType the service type for the call. Can be one of the following:
    314      *                    {@link #SERVICE_TYPE_NONE},
    315      *                    {@link #SERVICE_TYPE_NORMAL},
    316      *                    {@link #SERVICE_TYPE_EMERGENCY}
    317      * @param callType the call type. Can be one of the following:
    318      *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
    319      *                 {@link #CALL_TYPE_VOICE},
    320      *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
    321      *                 {@link #CALL_TYPE_VT},
    322      *                 {@link #CALL_TYPE_VT_TX},
    323      *                 {@link #CALL_TYPE_VT_RX},
    324      *                 {@link #CALL_TYPE_VT_NODIR},
    325      *                 {@link #CALL_TYPE_VS},
    326      *                 {@link #CALL_TYPE_VS_TX},
    327      *                 {@link #CALL_TYPE_VS_RX}
    328      */
    329     public ImsCallProfile(int serviceType, int callType) {
    330         mServiceType = serviceType;
    331         mCallType = callType;
    332         mCallExtras = new Bundle();
    333         mMediaProfile = new ImsStreamMediaProfile();
    334     }
    335 
    336     /**
    337      * Constructor.
    338      *
    339      * @param serviceType the service type for the call. Can be one of the following:
    340      *                    {@link #SERVICE_TYPE_NONE},
    341      *                    {@link #SERVICE_TYPE_NORMAL},
    342      *                    {@link #SERVICE_TYPE_EMERGENCY}
    343      * @param callType the call type. Can be one of the following:
    344      *                 {@link #CALL_TYPE_VOICE_N_VIDEO},
    345      *                 {@link #CALL_TYPE_VOICE},
    346      *                 {@link #CALL_TYPE_VIDEO_N_VOICE},
    347      *                 {@link #CALL_TYPE_VT},
    348      *                 {@link #CALL_TYPE_VT_TX},
    349      *                 {@link #CALL_TYPE_VT_RX},
    350      *                 {@link #CALL_TYPE_VT_NODIR},
    351      *                 {@link #CALL_TYPE_VS},
    352      *                 {@link #CALL_TYPE_VS_TX},
    353      *                 {@link #CALL_TYPE_VS_RX}
    354      * @param callExtras A bundle with the call extras.
    355      * @param mediaProfile The IMS stream media profile.
    356      */
    357     public ImsCallProfile(int serviceType, int callType, Bundle callExtras,
    358             ImsStreamMediaProfile mediaProfile) {
    359         mServiceType = serviceType;
    360         mCallType = callType;
    361         mCallExtras = callExtras;
    362         mMediaProfile = mediaProfile;
    363     }
    364 
    365     public String getCallExtra(String name) {
    366         return getCallExtra(name, "");
    367     }
    368 
    369     public String getCallExtra(String name, String defaultValue) {
    370         if (mCallExtras == null) {
    371             return defaultValue;
    372         }
    373 
    374         return mCallExtras.getString(name, defaultValue);
    375     }
    376 
    377     public boolean getCallExtraBoolean(String name) {
    378         return getCallExtraBoolean(name, false);
    379     }
    380 
    381     public boolean getCallExtraBoolean(String name, boolean defaultValue) {
    382         if (mCallExtras == null) {
    383             return defaultValue;
    384         }
    385 
    386         return mCallExtras.getBoolean(name, defaultValue);
    387     }
    388 
    389     public int getCallExtraInt(String name) {
    390         return getCallExtraInt(name, -1);
    391     }
    392 
    393     public int getCallExtraInt(String name, int defaultValue) {
    394         if (mCallExtras == null) {
    395             return defaultValue;
    396         }
    397 
    398         return mCallExtras.getInt(name, defaultValue);
    399     }
    400 
    401     public void setCallExtra(String name, String value) {
    402         if (mCallExtras != null) {
    403             mCallExtras.putString(name, value);
    404         }
    405     }
    406 
    407     public void setCallExtraBoolean(String name, boolean value) {
    408         if (mCallExtras != null) {
    409             mCallExtras.putBoolean(name, value);
    410         }
    411     }
    412 
    413     public void setCallExtraInt(String name, int value) {
    414         if (mCallExtras != null) {
    415             mCallExtras.putInt(name, value);
    416         }
    417     }
    418 
    419     public void updateCallType(ImsCallProfile profile) {
    420         mCallType = profile.mCallType;
    421     }
    422 
    423     public void updateCallExtras(ImsCallProfile profile) {
    424         mCallExtras.clear();
    425         mCallExtras = (Bundle) profile.mCallExtras.clone();
    426     }
    427 
    428     /**
    429      * Updates the media profile for the call.
    430      *
    431      * @param profile Call profile with new media profile.
    432      */
    433     public void updateMediaProfile(ImsCallProfile profile) {
    434         mMediaProfile = profile.mMediaProfile;
    435     }
    436 
    437 
    438     @Override
    439     public String toString() {
    440         return "{ serviceType=" + mServiceType +
    441                 ", callType=" + mCallType +
    442                 ", restrictCause=" + mRestrictCause +
    443                 ", mediaProfile=" + mMediaProfile.toString() + " }";
    444     }
    445 
    446     @Override
    447     public int describeContents() {
    448         return 0;
    449     }
    450 
    451     @Override
    452     public void writeToParcel(Parcel out, int flags) {
    453         Bundle filteredExtras = maybeCleanseExtras(mCallExtras);
    454         out.writeInt(mServiceType);
    455         out.writeInt(mCallType);
    456         out.writeBundle(filteredExtras);
    457         out.writeParcelable(mMediaProfile, 0);
    458     }
    459 
    460     private void readFromParcel(Parcel in) {
    461         mServiceType = in.readInt();
    462         mCallType = in.readInt();
    463         mCallExtras = in.readBundle();
    464         mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader());
    465     }
    466 
    467     public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
    468         @Override
    469         public ImsCallProfile createFromParcel(Parcel in) {
    470             return new ImsCallProfile(in);
    471         }
    472 
    473         @Override
    474         public ImsCallProfile[] newArray(int size) {
    475             return new ImsCallProfile[size];
    476         }
    477     };
    478 
    479     public int getServiceType() {
    480         return mServiceType;
    481     }
    482 
    483     public int getCallType() {
    484         return mCallType;
    485     }
    486 
    487     public int getRestrictCause() {
    488         return mRestrictCause;
    489     }
    490 
    491     public Bundle getCallExtras() {
    492         return mCallExtras;
    493     }
    494 
    495     public ImsStreamMediaProfile getMediaProfile() {
    496         return mMediaProfile;
    497     }
    498 
    499     /**
    500      * Converts from the call types defined in {@link ImsCallProfile} to the
    501      * video state values defined in {@link VideoProfile}.
    502      *
    503      * @param callProfile The call profile.
    504      * @return The video state.
    505      */
    506     public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) {
    507         int videostate = getVideoStateFromCallType(callProfile.mCallType);
    508         if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) {
    509             videostate |= VideoProfile.STATE_PAUSED;
    510         } else {
    511             videostate &= ~VideoProfile.STATE_PAUSED;
    512         }
    513         return videostate;
    514     }
    515 
    516     /**
    517      * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state.
    518      * @param callType The call type.
    519      * @return The video state.
    520      */
    521     public static int getVideoStateFromCallType(int callType) {
    522         int videostate = VideoProfile.STATE_AUDIO_ONLY;
    523         switch (callType) {
    524             case CALL_TYPE_VT_TX:
    525                 videostate = VideoProfile.STATE_TX_ENABLED;
    526                 break;
    527             case CALL_TYPE_VT_RX:
    528                 videostate = VideoProfile.STATE_RX_ENABLED;
    529                 break;
    530             case CALL_TYPE_VT:
    531                 videostate = VideoProfile.STATE_BIDIRECTIONAL;
    532                 break;
    533             case CALL_TYPE_VOICE:
    534                 videostate = VideoProfile.STATE_AUDIO_ONLY;
    535                 break;
    536             default:
    537                 videostate = VideoProfile.STATE_AUDIO_ONLY;
    538                 break;
    539         }
    540         return videostate;
    541     }
    542 
    543     /**
    544      * Converts from the video state values defined in {@link VideoProfile}
    545      * to the call types defined in {@link ImsCallProfile}.
    546      *
    547      * @param videoState The video state.
    548      * @return The call type.
    549      */
    550     public static int getCallTypeFromVideoState(int videoState) {
    551         boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED);
    552         boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED);
    553         boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED);
    554         if (isPaused) {
    555             return ImsCallProfile.CALL_TYPE_VT_NODIR;
    556         } else if (videoTx && !videoRx) {
    557             return ImsCallProfile.CALL_TYPE_VT_TX;
    558         } else if (!videoTx && videoRx) {
    559             return ImsCallProfile.CALL_TYPE_VT_RX;
    560         } else if (videoTx && videoRx) {
    561             return ImsCallProfile.CALL_TYPE_VT;
    562         }
    563         return ImsCallProfile.CALL_TYPE_VOICE;
    564     }
    565 
    566     /**
    567      * Badly named old method, kept for compatibility.
    568      * See {@link #presentationToOir(int)}.
    569      * @hide
    570      */
    571     public static int presentationToOIR(int presentation) {
    572         switch (presentation) {
    573             case PhoneConstants.PRESENTATION_RESTRICTED:
    574                 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
    575             case PhoneConstants.PRESENTATION_ALLOWED:
    576                 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
    577             case PhoneConstants.PRESENTATION_PAYPHONE:
    578                 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
    579             case PhoneConstants.PRESENTATION_UNKNOWN:
    580                 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
    581             default:
    582                 return ImsCallProfile.OIR_DEFAULT;
    583         }
    584     }
    585 
    586     /**
    587      * Translate presentation value to OIR value
    588      * @param presentation
    589      * @return OIR values
    590      */
    591     public static int presentationToOir(int presentation) {
    592         return presentationToOIR(presentation);
    593     }
    594 
    595     /**
    596      * Translate OIR value to presentation value
    597      * @param oir value
    598      * @return presentation value
    599      * @hide
    600      */
    601     public static int OIRToPresentation(int oir) {
    602         switch(oir) {
    603             case ImsCallProfile.OIR_PRESENTATION_RESTRICTED:
    604                 return PhoneConstants.PRESENTATION_RESTRICTED;
    605             case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
    606                 return PhoneConstants.PRESENTATION_ALLOWED;
    607             case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
    608                 return PhoneConstants.PRESENTATION_PAYPHONE;
    609             case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
    610                 return PhoneConstants.PRESENTATION_UNKNOWN;
    611             default:
    612                 return PhoneConstants.PRESENTATION_UNKNOWN;
    613         }
    614     }
    615 
    616     /**
    617      * Checks if video call is paused
    618      * @return true if call is video paused
    619      */
    620     public boolean isVideoPaused() {
    621         return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE;
    622     }
    623 
    624     /**
    625      * Determines if the {@link ImsCallProfile} represents a video call.
    626      *
    627      * @return {@code true} if the profile is for a video call, {@code false} otherwise.
    628      */
    629     public boolean isVideoCall() {
    630         return VideoProfile.isVideo(getVideoStateFromCallType(mCallType));
    631     }
    632 
    633     /**
    634      * Cleanses a {@link Bundle} to ensure that it contains only data of type:
    635      * 1. Primitive data types (e.g. int, bool, and other values determined by
    636      * {@link android.os.PersistableBundle#isValidType(Object)}).
    637      * 2. Other Bundles.
    638      * 3. {@link Parcelable} objects in the {@code android.*} namespace.
    639      * @param extras the source {@link Bundle}
    640      * @return where all elements are valid types the source {@link Bundle} is returned unmodified,
    641      *      otherwise a copy of the {@link Bundle} with the invalid elements is returned.
    642      */
    643     private Bundle maybeCleanseExtras(Bundle extras) {
    644         if (extras == null) {
    645             return null;
    646         }
    647 
    648         int startSize = extras.size();
    649         Bundle filtered = extras.filterValues();
    650         int endSize = filtered.size();
    651         if (startSize != endSize) {
    652             Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were "
    653                     + "removed - only primitive types and system parcelables are permitted.");
    654         }
    655         return filtered;
    656     }
    657 
    658     /**
    659      * Determines if a video state is set in a video state bit-mask.
    660      *
    661      * @param videoState The video state bit mask.
    662      * @param videoStateToCheck The particular video state to check.
    663      * @return True if the video state is set in the bit-mask.
    664      */
    665     private static boolean isVideoStateSet(int videoState, int videoStateToCheck) {
    666         return (videoState & videoStateToCheck) == videoStateToCheck;
    667     }
    668 }
    669