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 /** 118 * Integer extra properties 119 * oir : Rule for originating identity (number) presentation, MO/MT. 120 * {@link ImsCallProfile#OIR_DEFAULT} 121 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 122 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 123 * cnap : Rule for calling name presentation 124 * {@link ImsCallProfile#OIR_DEFAULT} 125 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} 126 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} 127 * dialstring : To identify the Ims call type, MO 128 * {@link ImsCallProfile#DIALSTRING_NORMAL_CALL} 129 * {@link ImsCallProfile#DIALSTRING_SS_CONF} 130 * {@link ImsCallProfile#DIALSTRING_USSD} 131 */ 132 public static final String EXTRA_OIR = "oir"; 133 public static final String EXTRA_CNAP = "cnap"; 134 public static final String EXTRA_DIALSTRING = "dialstring"; 135 136 /** 137 * Values for EXTRA_OIR / EXTRA_CNAP 138 */ 139 public static final int OIR_DEFAULT = 0; // "user subscription default value" 140 public static final int OIR_PRESENTATION_RESTRICTED = 1; 141 public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; 142 143 /** 144 * Values for EXTRA_DIALSTRING 145 */ 146 // default (normal call) 147 public static final int DIALSTRING_NORMAL = 0; 148 // Call for SIP-based user configuration 149 public static final int DIALSTRING_SS_CONF = 1; 150 // Call for USSD message 151 public static final int DIALSTRING_USSD = 2; 152 153 /** 154 * String extra properties 155 * oi : Originating identity (number), MT only 156 * cna : Calling name 157 * ussd : For network-initiated USSD, MT only 158 * remote_uri : Connected user identity (it can be used for the conference) 159 */ 160 public static final String EXTRA_OI = "oi"; 161 public static final String EXTRA_CNA = "cna"; 162 public static final String EXTRA_USSD = "ussd"; 163 public static final String EXTRA_REMOTE_URI = "remote_uri"; 164 165 public int mServiceType; 166 public int mCallType; 167 public Bundle mCallExtras; 168 public ImsStreamMediaProfile mMediaProfile; 169 170 171 172 public ImsCallProfile(Parcel in) { 173 readFromParcel(in); 174 } 175 176 public ImsCallProfile() { 177 mServiceType = SERVICE_TYPE_NORMAL; 178 mCallType = CALL_TYPE_VOICE_N_VIDEO; 179 mCallExtras = new Bundle(); 180 mMediaProfile = new ImsStreamMediaProfile(); 181 } 182 183 public ImsCallProfile(int serviceType, int callType) { 184 mServiceType = serviceType; 185 mCallType = callType; 186 mCallExtras = new Bundle(); 187 mMediaProfile = new ImsStreamMediaProfile(); 188 } 189 190 public String getCallExtra(String name) { 191 return getCallExtra(name, ""); 192 } 193 194 public String getCallExtra(String name, String defaultValue) { 195 if (mCallExtras == null) { 196 return defaultValue; 197 } 198 199 return mCallExtras.getString(name, defaultValue); 200 } 201 202 public boolean getCallExtraBoolean(String name) { 203 return getCallExtraBoolean(name, false); 204 } 205 206 public boolean getCallExtraBoolean(String name, boolean defaultValue) { 207 if (mCallExtras == null) { 208 return defaultValue; 209 } 210 211 return mCallExtras.getBoolean(name, defaultValue); 212 } 213 214 public int getCallExtraInt(String name) { 215 return getCallExtraInt(name, -1); 216 } 217 218 public int getCallExtraInt(String name, int defaultValue) { 219 if (mCallExtras == null) { 220 return defaultValue; 221 } 222 223 return mCallExtras.getInt(name, defaultValue); 224 } 225 226 public void setCallExtra(String name, String value) { 227 if (mCallExtras != null) { 228 mCallExtras.putString(name, value); 229 } 230 } 231 232 public void setCallExtraBoolean(String name, boolean value) { 233 if (mCallExtras != null) { 234 mCallExtras.putBoolean(name, value); 235 } 236 } 237 238 public void setCallExtraInt(String name, int value) { 239 if (mCallExtras != null) { 240 mCallExtras.putInt(name, value); 241 } 242 } 243 244 public void updateCallType(ImsCallProfile profile) { 245 mCallType = profile.mCallType; 246 } 247 248 public void updateCallExtras(ImsCallProfile profile) { 249 mCallExtras.clear(); 250 mCallExtras = (Bundle) profile.mCallExtras.clone(); 251 } 252 253 @Override 254 public String toString() { 255 return "{ serviceType=" + mServiceType + 256 ", callType=" + mCallType + 257 ", callExtras=" + mCallExtras.toString() + 258 ", mediaProfile=" + mMediaProfile.toString() + " }"; 259 } 260 261 @Override 262 public int describeContents() { 263 return 0; 264 } 265 266 @Override 267 public void writeToParcel(Parcel out, int flags) { 268 out.writeInt(mServiceType); 269 out.writeInt(mCallType); 270 out.writeParcelable(mCallExtras, 0); 271 out.writeParcelable(mMediaProfile, 0); 272 } 273 274 private void readFromParcel(Parcel in) { 275 mServiceType = in.readInt(); 276 mCallType = in.readInt(); 277 mCallExtras = in.readParcelable(null); 278 mMediaProfile = in.readParcelable(null); 279 } 280 281 public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { 282 @Override 283 public ImsCallProfile createFromParcel(Parcel in) { 284 return new ImsCallProfile(in); 285 } 286 287 @Override 288 public ImsCallProfile[] newArray(int size) { 289 return new ImsCallProfile[size]; 290 } 291 }; 292 293 /** 294 * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the 295 * video state values defined in {@link VideoProfile}. 296 * 297 * @param callType The call type. 298 * @return The video state. 299 */ 300 public static int getVideoStateFromCallType(int callType) { 301 switch (callType) { 302 case CALL_TYPE_VT_NODIR: 303 return VideoProfile.VideoState.PAUSED | 304 VideoProfile.VideoState.BIDIRECTIONAL; 305 case CALL_TYPE_VT_TX: 306 return VideoProfile.VideoState.TX_ENABLED; 307 case CALL_TYPE_VT_RX: 308 return VideoProfile.VideoState.RX_ENABLED; 309 case CALL_TYPE_VT: 310 return VideoProfile.VideoState.BIDIRECTIONAL; 311 case CALL_TYPE_VOICE: 312 return VideoProfile.VideoState.AUDIO_ONLY; 313 default: 314 return VideoProfile.VideoState.AUDIO_ONLY; 315 } 316 } 317 318 /** 319 * Converts from the video state values defined in {@link VideoProfile} 320 * to the call types defined in {@link ImsCallProfile}. 321 * 322 * @param videoState The video state. 323 * @return The call type. 324 */ 325 public static int getCallTypeFromVideoState(int videoState) { 326 boolean videoTx = isVideoStateSet(videoState, VideoProfile.VideoState.TX_ENABLED); 327 boolean videoRx = isVideoStateSet(videoState, VideoProfile.VideoState.RX_ENABLED); 328 boolean isPaused = isVideoStateSet(videoState, VideoProfile.VideoState.PAUSED); 329 if (isPaused) { 330 return ImsCallProfile.CALL_TYPE_VT_NODIR; 331 } else if (videoTx && !videoRx) { 332 return ImsCallProfile.CALL_TYPE_VT_TX; 333 } else if (!videoTx && videoRx) { 334 return ImsCallProfile.CALL_TYPE_VT_RX; 335 } else if (videoTx && videoRx) { 336 return ImsCallProfile.CALL_TYPE_VT; 337 } 338 return ImsCallProfile.CALL_TYPE_VOICE; 339 } 340 341 /** 342 * Translate presentation value to OIR value 343 * @param presentation 344 * @return OIR valuse 345 */ 346 public static int presentationToOIR(int presentation) { 347 switch (presentation) { 348 case PhoneConstants.PRESENTATION_RESTRICTED: 349 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED; 350 case PhoneConstants.PRESENTATION_ALLOWED: 351 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED; 352 default: 353 return ImsCallProfile.OIR_DEFAULT; 354 } 355 } 356 357 /** 358 * Translate OIR value to presentation value 359 * @param oir value 360 * @return presentation value 361 */ 362 public static int OIRToPresentation(int oir) { 363 switch(oir) { 364 case ImsCallProfile.OIR_PRESENTATION_RESTRICTED: 365 return PhoneConstants.PRESENTATION_RESTRICTED; 366 case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED: 367 return PhoneConstants.PRESENTATION_ALLOWED; 368 default: 369 return PhoneConstants.PRESENTATION_UNKNOWN; 370 } 371 } 372 373 /** 374 * Determines if a video state is set in a video state bit-mask. 375 * 376 * @param videoState The video state bit mask. 377 * @param videoStateToCheck The particular video state to check. 378 * @return True if the video state is set in the bit-mask. 379 */ 380 private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { 381 return (videoState & videoStateToCheck) == videoStateToCheck; 382 } 383 } 384