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 ImsCallProfile(Parcel in)222 public ImsCallProfile(Parcel in) { 223 readFromParcel(in); 224 } 225 ImsCallProfile()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 ImsCallProfile(int serviceType, int callType)233 public ImsCallProfile(int serviceType, int callType) { 234 mServiceType = serviceType; 235 mCallType = callType; 236 mCallExtras = new Bundle(); 237 mMediaProfile = new ImsStreamMediaProfile(); 238 } 239 getCallExtra(String name)240 public String getCallExtra(String name) { 241 return getCallExtra(name, ""); 242 } 243 getCallExtra(String name, String defaultValue)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 getCallExtraBoolean(String name)252 public boolean getCallExtraBoolean(String name) { 253 return getCallExtraBoolean(name, false); 254 } 255 getCallExtraBoolean(String name, boolean defaultValue)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 getCallExtraInt(String name)264 public int getCallExtraInt(String name) { 265 return getCallExtraInt(name, -1); 266 } 267 getCallExtraInt(String name, int defaultValue)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 setCallExtra(String name, String value)276 public void setCallExtra(String name, String value) { 277 if (mCallExtras != null) { 278 mCallExtras.putString(name, value); 279 } 280 } 281 setCallExtraBoolean(String name, boolean value)282 public void setCallExtraBoolean(String name, boolean value) { 283 if (mCallExtras != null) { 284 mCallExtras.putBoolean(name, value); 285 } 286 } 287 setCallExtraInt(String name, int value)288 public void setCallExtraInt(String name, int value) { 289 if (mCallExtras != null) { 290 mCallExtras.putInt(name, value); 291 } 292 } 293 updateCallType(ImsCallProfile profile)294 public void updateCallType(ImsCallProfile profile) { 295 mCallType = profile.mCallType; 296 } 297 updateCallExtras(ImsCallProfile profile)298 public void updateCallExtras(ImsCallProfile profile) { 299 mCallExtras.clear(); 300 mCallExtras = (Bundle) profile.mCallExtras.clone(); 301 } 302 303 @Override toString()304 public String toString() { 305 return "{ serviceType=" + mServiceType + 306 ", callType=" + mCallType + 307 ", restrictCause=" + mRestrictCause + 308 ", mediaProfile=" + mMediaProfile.toString() + " }"; 309 } 310 311 @Override describeContents()312 public int describeContents() { 313 return 0; 314 } 315 316 @Override writeToParcel(Parcel out, int flags)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 readFromParcel(Parcel in)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 */ getVideoStateFromImsCallProfile(ImsCallProfile callProfile)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 */ getVideoStateFromCallType(int callType)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 */ getCallTypeFromVideoState(int videoState)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 */ presentationToOIR(int presentation)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 */ OIRToPresentation(int oir)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 */ isVideoPaused()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 */ isVideoCall()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 */ isVideoStateSet(int videoState, int videoStateToCheck)474 private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { 475 return (videoState & videoStateToCheck) == videoStateToCheck; 476 } 477 } 478