Home | History | Annotate | Download | only in ims
      1 /*
      2  * Copyright (c) 2013 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 com.android.ims;
     18 
     19 import android.os.Bundle;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 import android.telecom.VideoProfile;
     23 
     24 import com.android.internal.telephony.PhoneConstants;
     25 
     26 /**
     27  * Parcelable object to handle IMS call profile.
     28  * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
     29  * It provides the service and call type, the additional information related to the call.
     30  *
     31  * @hide
     32  */
     33 public class ImsCallProfile implements Parcelable {
     34     private static final String TAG = "ImsCallProfile";
     35 
     36     /**
     37      * Service types
     38      */
     39     /**
     40      * It is for a special case. It helps that the application can make a call
     41      * without IMS connection (not registered).
     42      * In the moment of the call initiation, the device try to connect to the IMS network
     43      * and initiates the call.
     44      */
     45     public static final int SERVICE_TYPE_NONE = 0;
     46     /**
     47      * It is a default type and can be selected when the device is connected to the IMS network.
     48      */
     49     public static final int SERVICE_TYPE_NORMAL = 1;
     50     /**
     51      * It is for an emergency call.
     52      */
     53     public static final int SERVICE_TYPE_EMERGENCY = 2;
     54 
     55     /**
     56      * Call types
     57      */
     58     /**
     59      * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     60      */
     61     public static final int CALL_TYPE_VOICE_N_VIDEO = 1;
     62     /**
     63      * IR.92 (Voice only)
     64      */
     65     public static final int CALL_TYPE_VOICE = 2;
     66     /**
     67      * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade)
     68      */
     69     public static final int CALL_TYPE_VIDEO_N_VOICE = 3;
     70     /**
     71      * Video Telephony (audio / video two way)
     72      */
     73     public static final int CALL_TYPE_VT = 4;
     74     /**
     75      * Video Telephony (audio two way / video TX one way)
     76      */
     77     public static final int CALL_TYPE_VT_TX = 5;
     78     /**
     79      * Video Telephony (audio two way / video RX one way)
     80      */
     81     public static final int CALL_TYPE_VT_RX = 6;
     82     /**
     83      * Video Telephony (audio two way / video inactive)
     84      */
     85     public static final int CALL_TYPE_VT_NODIR = 7;
     86     /**
     87      * VideoShare (video two way)
     88      */
     89     public static final int CALL_TYPE_VS = 8;
     90     /**
     91      * VideoShare (video TX one way)
     92      */
     93     public static final int CALL_TYPE_VS_TX = 9;
     94     /**
     95      * VideoShare (video RX one way)
     96      */
     97     public static final int CALL_TYPE_VS_RX = 10;
     98 
     99     /**
    100      * Extra properties for IMS call.
    101      */
    102     /**
    103      * Boolean extra properties - "true" / "false"
    104      *  conference : Indicates if the session is for the conference call or not.
    105      *  e_call : Indicates if the session is for the emergency call or not.
    106      *  vms : Indicates if the session is connected to the voice mail system or not.
    107      *  call_mode_changeable : Indicates if the session is able to upgrade/downgrade
    108      *      the video during voice call.
    109      *  conference_avail : Indicates if the session can be extended to the conference.
    110      */
    111     public static final String EXTRA_CONFERENCE = "conference";
    112     public static final String EXTRA_E_CALL = "e_call";
    113     public static final String EXTRA_VMS = "vms";
    114     public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";
    115     public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
    116 
    117     // Extra string for internal use only. OEMs should not use
    118     // this for packing extras.
    119     public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
    120 
    121     /**
    122      * Integer extra properties
    123      *  oir : Rule for originating identity (number) presentation, MO/MT.
    124      *      {@link ImsCallProfile#OIR_DEFAULT}
    125      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
    126      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
    127      *  cnap : Rule for calling name presentation
    128      *      {@link ImsCallProfile#OIR_DEFAULT}
    129      *      {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
    130      *      {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
    131      *  dialstring : To identify the Ims call type, MO
    132      *      {@link ImsCallProfile#DIALSTRING_NORMAL_CALL}
    133      *      {@link ImsCallProfile#DIALSTRING_SS_CONF}
    134      *      {@link ImsCallProfile#DIALSTRING_USSD}
    135      */
    136     public static final String EXTRA_OIR = "oir";
    137     public static final String EXTRA_CNAP = "cnap";
    138     public static final String EXTRA_DIALSTRING = "dialstring";
    139 
    140     /**
    141      * Values for EXTRA_OIR / EXTRA_CNAP
    142      */
    143     public static final int OIR_DEFAULT = 0;    // "user subscription default value"
    144     public static final int OIR_PRESENTATION_RESTRICTED = 1;
    145     public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
    146     public static final int OIR_PRESENTATION_UNKNOWN = 3;
    147     public static final int OIR_PRESENTATION_PAYPHONE = 4;
    148 
    149     /**
    150      * Values for EXTRA_DIALSTRING
    151      */
    152     // default (normal call)
    153     public static final int DIALSTRING_NORMAL = 0;
    154     // Call for SIP-based user configuration
    155     public static final int DIALSTRING_SS_CONF = 1;
    156     // Call for USSD message
    157     public static final int DIALSTRING_USSD = 2;
    158 
    159     /**
    160      * Values for causes that restrict call types
    161      */
    162     // Default cause not restricted at peer and HD is supported
    163     public static final int CALL_RESTRICT_CAUSE_NONE = 0;
    164     // Service not supported by RAT at peer
    165     public static final int CALL_RESTRICT_CAUSE_RAT = 1;
    166     // Service Disabled at peer
    167     public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
    168     // HD is not supported
    169     public static final int CALL_RESTRICT_CAUSE_HD = 3;
    170 
    171     /**
    172      * String extra properties
    173      *  oi : Originating identity (number), MT only
    174      *  cna : Calling name
    175      *  ussd : For network-initiated USSD, MT only
    176      *  remote_uri : Connected user identity (it can be used for the conference)
    177      *  ChildNum: Child number info.
    178      *  Codec: Codec info.
    179      *  DisplayText: Display text for the call.
    180      *  AdditionalCallInfo: Additional call info.
    181      *  CallPull: Boolean value specifying if the call is a pulled call.
    182      */
    183     public static final String EXTRA_OI = "oi";
    184     public static final String EXTRA_CNA = "cna";
    185     public static final String EXTRA_USSD = "ussd";
    186     public static final String EXTRA_REMOTE_URI = "remote_uri";
    187     public static final String EXTRA_CHILD_NUMBER = "ChildNum";
    188     public static final String EXTRA_CODEC = "Codec";
    189     public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
    190     public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
    191     public static final String EXTRA_IS_CALL_PULL = "CallPull";
    192 
    193     /**
    194      * Extra key which the RIL can use to indicate the radio technology used for a call.
    195      * Valid values are:
    196      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
    197      * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
    198      * {@code RIL_RADIO_TECHNOLOGY_*} constants.
    199      * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
    200      * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
    201      * "14" vs (int) 14).
    202      * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
    203      *      updateWifiStateFromExtras(Bundle)} to determine whether to set the
    204      * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
    205      */
    206     public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
    207 
    208     /**
    209      * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'.  Used to ensure
    210      * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE}
    211      * extra key.  Should be removed when the non-compliant modems are fixed.
    212      * @hide
    213      */
    214     public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech";
    215 
    216     public int mServiceType;
    217     public int mCallType;
    218     public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
    219     public Bundle mCallExtras;
    220     public ImsStreamMediaProfile mMediaProfile;
    221 
    222     public ImsCallProfile(Parcel in) {
    223         readFromParcel(in);
    224     }
    225 
    226     public ImsCallProfile() {
    227         mServiceType = SERVICE_TYPE_NORMAL;
    228         mCallType = CALL_TYPE_VOICE_N_VIDEO;
    229         mCallExtras = new Bundle();
    230         mMediaProfile = new ImsStreamMediaProfile();
    231     }
    232 
    233     public ImsCallProfile(int serviceType, int callType) {
    234         mServiceType = serviceType;
    235         mCallType = callType;
    236         mCallExtras = new Bundle();
    237         mMediaProfile = new ImsStreamMediaProfile();
    238     }
    239 
    240     public String getCallExtra(String name) {
    241         return getCallExtra(name, "");
    242     }
    243 
    244     public String getCallExtra(String name, String defaultValue) {
    245         if (mCallExtras == null) {
    246             return defaultValue;
    247         }
    248 
    249         return mCallExtras.getString(name, defaultValue);
    250     }
    251 
    252     public boolean getCallExtraBoolean(String name) {
    253         return getCallExtraBoolean(name, false);
    254     }
    255 
    256     public boolean getCallExtraBoolean(String name, boolean defaultValue) {
    257         if (mCallExtras == null) {
    258             return defaultValue;
    259         }
    260 
    261         return mCallExtras.getBoolean(name, defaultValue);
    262     }
    263 
    264     public int getCallExtraInt(String name) {
    265         return getCallExtraInt(name, -1);
    266     }
    267 
    268     public int getCallExtraInt(String name, int defaultValue) {
    269         if (mCallExtras == null) {
    270             return defaultValue;
    271         }
    272 
    273         return mCallExtras.getInt(name, defaultValue);
    274     }
    275 
    276     public void setCallExtra(String name, String value) {
    277         if (mCallExtras != null) {
    278             mCallExtras.putString(name, value);
    279         }
    280     }
    281 
    282     public void setCallExtraBoolean(String name, boolean value) {
    283         if (mCallExtras != null) {
    284             mCallExtras.putBoolean(name, value);
    285         }
    286     }
    287 
    288     public void setCallExtraInt(String name, int value) {
    289         if (mCallExtras != null) {
    290             mCallExtras.putInt(name, value);
    291         }
    292     }
    293 
    294     public void updateCallType(ImsCallProfile profile) {
    295         mCallType = profile.mCallType;
    296     }
    297 
    298     public void updateCallExtras(ImsCallProfile profile) {
    299         mCallExtras.clear();
    300         mCallExtras = (Bundle) profile.mCallExtras.clone();
    301     }
    302 
    303     @Override
    304     public String toString() {
    305         return "{ serviceType=" + mServiceType +
    306                 ", callType=" + mCallType +
    307                 ", restrictCause=" + mRestrictCause +
    308                 ", mediaProfile=" + mMediaProfile.toString() + " }";
    309     }
    310 
    311     @Override
    312     public int describeContents() {
    313         return 0;
    314     }
    315 
    316     @Override
    317     public void writeToParcel(Parcel out, int flags) {
    318         out.writeInt(mServiceType);
    319         out.writeInt(mCallType);
    320         out.writeParcelable(mCallExtras, 0);
    321         out.writeParcelable(mMediaProfile, 0);
    322     }
    323 
    324     private void readFromParcel(Parcel in) {
    325         mServiceType = in.readInt();
    326         mCallType = in.readInt();
    327         mCallExtras = in.readParcelable(null);
    328         mMediaProfile = in.readParcelable(null);
    329     }
    330 
    331     public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
    332         @Override
    333         public ImsCallProfile createFromParcel(Parcel in) {
    334             return new ImsCallProfile(in);
    335         }
    336 
    337         @Override
    338         public ImsCallProfile[] newArray(int size) {
    339             return new ImsCallProfile[size];
    340         }
    341     };
    342 
    343     /**
    344      * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the
    345      * video state values defined in {@link VideoProfile}.
    346      *
    347      * @param callProfile The call profile.
    348      * @return The video state.
    349      */
    350     public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) {
    351         int videostate = getVideoStateFromCallType(callProfile.mCallType);
    352         if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) {
    353             videostate |= VideoProfile.STATE_PAUSED;
    354         } else {
    355             videostate &= ~VideoProfile.STATE_PAUSED;
    356         }
    357         return videostate;
    358     }
    359 
    360     /**
    361      * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state.
    362      * @param callType The call type.
    363      * @return The video state.
    364      */
    365     public static int getVideoStateFromCallType(int callType) {
    366         int videostate = VideoProfile.STATE_AUDIO_ONLY;
    367         switch (callType) {
    368             case CALL_TYPE_VT_TX:
    369                 videostate = VideoProfile.STATE_TX_ENABLED;
    370                 break;
    371             case CALL_TYPE_VT_RX:
    372                 videostate = VideoProfile.STATE_RX_ENABLED;
    373                 break;
    374             case CALL_TYPE_VT:
    375                 videostate = VideoProfile.STATE_BIDIRECTIONAL;
    376                 break;
    377             case CALL_TYPE_VOICE:
    378                 videostate = VideoProfile.STATE_AUDIO_ONLY;
    379                 break;
    380             default:
    381                 videostate = VideoProfile.STATE_AUDIO_ONLY;
    382                 break;
    383         }
    384         return videostate;
    385     }
    386 
    387     /**
    388      * Converts from the video state values defined in {@link VideoProfile}
    389      * to the call types defined in {@link ImsCallProfile}.
    390      *
    391      * @param videoState The video state.
    392      * @return The call type.
    393      */
    394     public static int getCallTypeFromVideoState(int videoState) {
    395         boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED);
    396         boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED);
    397         boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED);
    398         if (isPaused) {
    399             return ImsCallProfile.CALL_TYPE_VT_NODIR;
    400         } else if (videoTx && !videoRx) {
    401             return ImsCallProfile.CALL_TYPE_VT_TX;
    402         } else if (!videoTx && videoRx) {
    403             return ImsCallProfile.CALL_TYPE_VT_RX;
    404         } else if (videoTx && videoRx) {
    405             return ImsCallProfile.CALL_TYPE_VT;
    406         }
    407         return ImsCallProfile.CALL_TYPE_VOICE;
    408     }
    409 
    410     /**
    411      * Translate presentation value to OIR value
    412      * @param presentation
    413      * @return OIR valuse
    414      */
    415     public static int presentationToOIR(int presentation) {
    416         switch (presentation) {
    417             case PhoneConstants.PRESENTATION_RESTRICTED:
    418                 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
    419             case PhoneConstants.PRESENTATION_ALLOWED:
    420                 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
    421             case PhoneConstants.PRESENTATION_PAYPHONE:
    422                 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
    423             case PhoneConstants.PRESENTATION_UNKNOWN:
    424                 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
    425             default:
    426                 return ImsCallProfile.OIR_DEFAULT;
    427         }
    428     }
    429 
    430     /**
    431      * Translate OIR value to presentation value
    432      * @param oir value
    433      * @return presentation value
    434      */
    435     public static int OIRToPresentation(int oir) {
    436         switch(oir) {
    437             case ImsCallProfile.OIR_PRESENTATION_RESTRICTED:
    438                 return PhoneConstants.PRESENTATION_RESTRICTED;
    439             case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
    440                 return PhoneConstants.PRESENTATION_ALLOWED;
    441             case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
    442                 return PhoneConstants.PRESENTATION_PAYPHONE;
    443             case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
    444                 return PhoneConstants.PRESENTATION_UNKNOWN;
    445             default:
    446                 return PhoneConstants.PRESENTATION_UNKNOWN;
    447         }
    448     }
    449 
    450     /**
    451      * Checks if video call is paused
    452      * @return true if call is video paused
    453      */
    454     public boolean isVideoPaused() {
    455         return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE;
    456     }
    457 
    458     /**
    459      * Determines if the {@link ImsCallProfile} represents a video call.
    460      *
    461      * @return {@code true} if the profile is for a video call, {@code false} otherwise.
    462      */
    463     public boolean isVideoCall() {
    464         return VideoProfile.isVideo(getVideoStateFromCallType(mCallType));
    465     }
    466 
    467     /**
    468      * Determines if a video state is set in a video state bit-mask.
    469      *
    470      * @param videoState The video state bit mask.
    471      * @param videoStateToCheck The particular video state to check.
    472      * @return True if the video state is set in the bit-mask.
    473      */
    474     private static boolean isVideoStateSet(int videoState, int videoStateToCheck) {
    475         return (videoState & videoStateToCheck) == videoStateToCheck;
    476     }
    477 }
    478